Skip to content

Commit 5e9a717

Browse files
authored
Update GetOnlineFeatures method in sdks (#1052)
* Update java sdk Signed-off-by: Terence <terencelimxp@gmail.com> * Update python sdk Signed-off-by: Terence <terencelimxp@gmail.com> * Update go protos Signed-off-by: Terence <terencelimxp@gmail.com> * Update go sdk Signed-off-by: Terence <terencelimxp@gmail.com> * Allow project to be unspecified for default proj Signed-off-by: Terence <terencelimxp@gmail.com> * Address PR comments Signed-off-by: Terence <terencelimxp@gmail.com> * Some cleanups Signed-off-by: Terence <terencelimxp@gmail.com>
1 parent 08b37c1 commit 5e9a717

File tree

16 files changed

+621
-275
lines changed

16 files changed

+621
-275
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ require (
2525
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
2626
golang.org/x/net v0.0.0-20200822124328-c89045814202
2727
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9 // indirect
28-
golang.org/x/tools v0.0.0-20201011145850-ed2f50202694 // indirect
28+
golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752 // indirect
2929
google.golang.org/grpc v1.29.1
3030
google.golang.org/protobuf v1.25.0 // indirect
3131
gopkg.in/russross/blackfriday.v2 v2.0.0 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,8 @@ golang.org/x/tools v0.0.0-20201011145850-ed2f50202694 h1:BANdcOVw3KTuUiyfDp7wrzC
494494
golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
495495
golang.org/x/tools v0.0.0-20201013053347-2db1cd791039 h1:kLBxO4OPBgPwjg8Vvu+/0DCHIfDwYIGNFcD66NU9kpo=
496496
golang.org/x/tools v0.0.0-20201013053347-2db1cd791039/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
497+
golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752 h1:2ntEwh02rqo2jSsrYmp4yKHHjh0CbXP3ZtSUetSB+q8=
498+
golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
497499
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
498500
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
499501
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=

sdk/go/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func (fc *GrpcClient) GetOnlineFeatures(ctx context.Context, req *OnlineFeatures
9797
if err != nil {
9898
return nil, err
9999
}
100-
resp, err := fc.cli.GetOnlineFeatures(ctx, featuresRequest)
100+
resp, err := fc.cli.GetOnlineFeaturesV2(ctx, featuresRequest)
101101

102102
// collect unqiue entity refs from entity rows
103103
entityRefs := make(map[string]struct{})

sdk/go/client_test.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ func TestGetOnlineFeatures(t *testing.T) {
2626
req: OnlineFeaturesRequest{
2727
Features: []string{
2828
"driver:rating",
29-
"rating",
30-
"null_value",
29+
"driver:null_value",
3130
},
3231
Entities: []Row{
3332
{"driver_id": Int64Val(1)},
@@ -39,14 +38,12 @@ func TestGetOnlineFeatures(t *testing.T) {
3938
FieldValues: []*serving.GetOnlineFeaturesResponse_FieldValues{
4039
{
4140
Fields: map[string]*types.Value{
42-
"driver:rating": Int64Val(1),
43-
"rating": Int64Val(1),
44-
"null_value": {},
41+
"driver:rating": Int64Val(1),
42+
"driver:null_value": {},
4543
},
4644
Statuses: map[string]serving.GetOnlineFeaturesResponse_FieldStatus{
47-
"driver:rating": serving.GetOnlineFeaturesResponse_PRESENT,
48-
"rating": serving.GetOnlineFeaturesResponse_PRESENT,
49-
"null_value": serving.GetOnlineFeaturesResponse_NULL_VALUE,
45+
"driver:rating": serving.GetOnlineFeaturesResponse_PRESENT,
46+
"driver:null_value": serving.GetOnlineFeaturesResponse_NULL_VALUE,
5047
},
5148
},
5249
},
@@ -65,7 +62,7 @@ func TestGetOnlineFeatures(t *testing.T) {
6562
_, traceCtx := opentracing.StartSpanFromContext(ctx, "get_online_features")
6663
rawRequest, _ := tc.req.buildRequest()
6764
resp := tc.want.RawResponse
68-
cli.EXPECT().GetOnlineFeatures(traceCtx, rawRequest).Return(resp, nil).Times(1)
65+
cli.EXPECT().GetOnlineFeaturesV2(traceCtx, rawRequest).Return(resp, nil).Times(1)
6966

7067
client := &GrpcClient{
7168
cli: cli,

sdk/go/protos/feast/core/DataSource.pb.go

Lines changed: 84 additions & 71 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/go/request.go

Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ var (
1010
// ErrInvalidFeatureRef indicates that the user has provided a feature reference
1111
// with the wrong structure or contents
1212
ErrInvalidFeatureRef = "Invalid Feature Reference %s provided, " +
13-
"feature reference must be in the format [featureset:]name"
13+
"feature reference must be in the format featureTableName:featureName"
1414
)
1515

16-
// OnlineFeaturesRequest wrapper on feast.serving.GetOnlineFeaturesRequest.
16+
// OnlineFeaturesRequest wrapper on feast.serving.GetOnlineFeaturesRequestV2.
1717
type OnlineFeaturesRequest struct {
1818
// Features is the list of features to obtain from Feast. Each feature can be given as
19-
// the format feature_set:feature, where "feature_set" & "feature" are feature set name
19+
// the format feature_table:feature, where "feature_table" & "feature" are feature table name
2020
// and feature name respectively. The only required components is feature name.
2121
Features []string
2222

@@ -26,41 +26,37 @@ type OnlineFeaturesRequest struct {
2626
// Project optionally specifies the project override. If specified, uses given project for retrieval.
2727
// Overrides the projects specified in Feature References if also specified.
2828
Project string
29-
30-
// whether to omit the entities fields in the response.
31-
OmitEntities bool
3229
}
3330

3431
// Builds the feast-specified request payload from the wrapper.
35-
func (r OnlineFeaturesRequest) buildRequest() (*serving.GetOnlineFeaturesRequest, error) {
32+
func (r OnlineFeaturesRequest) buildRequest() (*serving.GetOnlineFeaturesRequestV2, error) {
3633
featureRefs, err := buildFeatureRefs(r.Features)
3734
if err != nil {
3835
return nil, err
3936
}
4037

4138
// build request entity rows from native entities
42-
entityRows := make([]*serving.GetOnlineFeaturesRequest_EntityRow, len(r.Entities))
39+
entityRows := make([]*serving.GetOnlineFeaturesRequestV2_EntityRow, len(r.Entities))
4340
for i, entity := range r.Entities {
44-
entityRows[i] = &serving.GetOnlineFeaturesRequest_EntityRow{
41+
entityRows[i] = &serving.GetOnlineFeaturesRequestV2_EntityRow{
4542
Fields: entity,
4643
}
4744
}
4845

49-
return &serving.GetOnlineFeaturesRequest{
50-
Features: featureRefs,
51-
EntityRows: entityRows,
52-
OmitEntitiesInResponse: r.OmitEntities,
53-
Project: r.Project,
46+
return &serving.GetOnlineFeaturesRequestV2{
47+
Features: featureRefs,
48+
EntityRows: entityRows,
49+
Project: r.Project,
5450
}, nil
5551
}
5652

5753
// Creates a slice of FeatureReferences from string representation in
58-
// the format featureset:feature.
54+
// the format featuretable:feature.
5955
// featureRefStrs - string feature references to parse.
6056
// Returns parsed FeatureReferences.
6157
// Returns an error when the format of the string feature reference is invalid
62-
func buildFeatureRefs(featureRefStrs []string) ([]*serving.FeatureReference, error) {
63-
var featureRefs []*serving.FeatureReference
58+
func buildFeatureRefs(featureRefStrs []string) ([]*serving.FeatureReferenceV2, error) {
59+
var featureRefs []*serving.FeatureReferenceV2
6460

6561
for _, featureRefStr := range featureRefStrs {
6662
featureRef, err := parseFeatureRef(featureRefStr)
@@ -76,35 +72,21 @@ func buildFeatureRefs(featureRefStrs []string) ([]*serving.FeatureReference, err
7672
// featureRefStr - the string feature reference to parse.
7773
// Returns parsed FeatureReference.
7874
// Returns an error when the format of the string feature reference is invalid
79-
func parseFeatureRef(featureRefStr string) (*serving.FeatureReference, error) {
75+
func parseFeatureRef(featureRefStr string) (*serving.FeatureReferenceV2, error) {
8076
if len(featureRefStr) == 0 {
8177
return nil, fmt.Errorf(ErrInvalidFeatureRef, featureRefStr)
8278
}
8379

84-
var featureRef serving.FeatureReference
85-
if strings.Contains(featureRefStr, "/") {
80+
var featureRef serving.FeatureReferenceV2
81+
if strings.Contains(featureRefStr, "/") || !strings.Contains(featureRefStr, ":") {
8682
return nil, fmt.Errorf(ErrInvalidFeatureRef, featureRefStr)
8783
}
88-
// parse featureset if specified
84+
// parse featuretable if specified
8985
if strings.Contains(featureRefStr, ":") {
9086
refSplit := strings.Split(featureRefStr, ":")
91-
featureRef.FeatureSet, featureRefStr = refSplit[0], refSplit[1]
87+
featureRef.FeatureTable, featureRefStr = refSplit[0], refSplit[1]
9288
}
9389
featureRef.Name = featureRefStr
9490

9591
return &featureRef, nil
9692
}
97-
98-
// Converts a FeatureReference proto into a string
99-
// featureRef - The FeatureReference to render as string
100-
// Returns string representation of the given FeatureReference
101-
func toFeatureRefStr(featureRef *serving.FeatureReference) string {
102-
refStr := ""
103-
// In protov3, unset string and default to ""
104-
if len(featureRef.FeatureSet) > 0 {
105-
refStr += featureRef.FeatureSet + ":"
106-
}
107-
refStr += featureRef.Name
108-
109-
return refStr
110-
}

sdk/go/request_test.go

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func TestGetOnlineFeaturesRequest(t *testing.T) {
1313
tt := []struct {
1414
name string
1515
req OnlineFeaturesRequest
16-
want *serving.GetOnlineFeaturesRequest
16+
want *serving.GetOnlineFeaturesRequestV2
1717
wantErr bool
1818
err error
1919
}{
@@ -22,7 +22,6 @@ func TestGetOnlineFeaturesRequest(t *testing.T) {
2222
req: OnlineFeaturesRequest{
2323
Features: []string{
2424
"driver:driver_id",
25-
"driver_id",
2625
},
2726
Entities: []Row{
2827
{"entity1": Int64Val(1), "entity2": StrVal("bob")},
@@ -31,17 +30,14 @@ func TestGetOnlineFeaturesRequest(t *testing.T) {
3130
},
3231
Project: "driver_project",
3332
},
34-
want: &serving.GetOnlineFeaturesRequest{
35-
Features: []*serving.FeatureReference{
33+
want: &serving.GetOnlineFeaturesRequestV2{
34+
Features: []*serving.FeatureReferenceV2{
3635
{
37-
FeatureSet: "driver",
38-
Name: "driver_id",
39-
},
40-
{
41-
Name: "driver_id",
36+
FeatureTable: "driver",
37+
Name: "driver_id",
4238
},
4339
},
44-
EntityRows: []*serving.GetOnlineFeaturesRequest_EntityRow{
40+
EntityRows: []*serving.GetOnlineFeaturesRequestV2_EntityRow{
4541
{
4642
Fields: map[string]*types.Value{
4743
"entity1": Int64Val(1),
@@ -61,8 +57,7 @@ func TestGetOnlineFeaturesRequest(t *testing.T) {
6157
},
6258
},
6359
},
64-
OmitEntitiesInResponse: false,
65-
Project: "driver_project",
60+
Project: "driver_project",
6661
},
6762
wantErr: false,
6863
err: nil,
@@ -77,6 +72,16 @@ func TestGetOnlineFeaturesRequest(t *testing.T) {
7772
wantErr: true,
7873
err: fmt.Errorf(ErrInvalidFeatureRef, "/fs1:feature1"),
7974
},
75+
{
76+
name: "invalid_feature_name",
77+
req: OnlineFeaturesRequest{
78+
Features: []string{"feature1"},
79+
Entities: []Row{},
80+
Project: "my_project",
81+
},
82+
wantErr: true,
83+
err: fmt.Errorf(ErrInvalidFeatureRef, "feature1"),
84+
},
8085
}
8186
for _, tc := range tt {
8287
t.Run(tc.name, func(t *testing.T) {

sdk/go/response_test.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,22 @@ var response = OnlineFeaturesResponse{
1313
FieldValues: []*serving.GetOnlineFeaturesResponse_FieldValues{
1414
{
1515
Fields: map[string]*types.Value{
16-
"project1/feature1": Int64Val(1),
17-
"project1/feature2": {},
16+
"featuretable1:feature1": Int64Val(1),
17+
"featuretable1:feature2": {},
1818
},
1919
Statuses: map[string]serving.GetOnlineFeaturesResponse_FieldStatus{
20-
"project1/feature1": serving.GetOnlineFeaturesResponse_PRESENT,
21-
"project1/feature2": serving.GetOnlineFeaturesResponse_NULL_VALUE,
20+
"featuretable1:feature1": serving.GetOnlineFeaturesResponse_PRESENT,
21+
"featuretable1:feature2": serving.GetOnlineFeaturesResponse_NULL_VALUE,
2222
},
2323
},
2424
{
2525
Fields: map[string]*types.Value{
26-
"project1/feature1": Int64Val(2),
27-
"project1/feature2": Int64Val(2),
26+
"featuretable1:feature1": Int64Val(2),
27+
"featuretable1:feature2": Int64Val(2),
2828
},
2929
Statuses: map[string]serving.GetOnlineFeaturesResponse_FieldStatus{
30-
"project1/feature1": serving.GetOnlineFeaturesResponse_PRESENT,
31-
"project1/feature2": serving.GetOnlineFeaturesResponse_PRESENT,
30+
"featuretable1:feature1": serving.GetOnlineFeaturesResponse_PRESENT,
31+
"featuretable1:feature2": serving.GetOnlineFeaturesResponse_PRESENT,
3232
},
3333
},
3434
},
@@ -38,8 +38,8 @@ var response = OnlineFeaturesResponse{
3838
func TestOnlineFeaturesResponseToRow(t *testing.T) {
3939
actual := response.Rows()
4040
expected := []Row{
41-
{"project1/feature1": Int64Val(1), "project1/feature2": &types.Value{}},
42-
{"project1/feature1": Int64Val(2), "project1/feature2": Int64Val(2)},
41+
{"featuretable1:feature1": Int64Val(1), "featuretable1:feature2": &types.Value{}},
42+
{"featuretable1:feature1": Int64Val(2), "featuretable1:feature2": Int64Val(2)},
4343
}
4444
if len(expected) != len(actual) {
4545
t.Errorf("expected: %v, got: %v", expected, actual)
@@ -55,12 +55,12 @@ func TestOnlineFeaturesResponseoToStatuses(t *testing.T) {
5555
actual := response.Statuses()
5656
expected := []map[string]serving.GetOnlineFeaturesResponse_FieldStatus{
5757
{
58-
"project1/feature1": serving.GetOnlineFeaturesResponse_PRESENT,
59-
"project1/feature2": serving.GetOnlineFeaturesResponse_NULL_VALUE,
58+
"featuretable1:feature1": serving.GetOnlineFeaturesResponse_PRESENT,
59+
"featuretable1:feature2": serving.GetOnlineFeaturesResponse_NULL_VALUE,
6060
},
6161
{
62-
"project1/feature1": serving.GetOnlineFeaturesResponse_PRESENT,
63-
"project1/feature2": serving.GetOnlineFeaturesResponse_PRESENT,
62+
"featuretable1:feature1": serving.GetOnlineFeaturesResponse_PRESENT,
63+
"featuretable1:feature2": serving.GetOnlineFeaturesResponse_PRESENT,
6464
},
6565
}
6666
if len(expected) != len(actual) {
@@ -88,7 +88,7 @@ func TestOnlineFeaturesResponseToInt64Array(t *testing.T) {
8888
{
8989
name: "valid",
9090
args: args{
91-
order: []string{"project1/feature2", "project1/feature1"},
91+
order: []string{"featuretable1:feature2", "featuretable1:feature1"},
9292
fillNa: []int64{-1, -1},
9393
},
9494
want: [][]int64{{-1, 1}, {2, 2}},
@@ -97,7 +97,7 @@ func TestOnlineFeaturesResponseToInt64Array(t *testing.T) {
9797
{
9898
name: "length mismatch",
9999
args: args{
100-
order: []string{"fs:feature2", "fs:feature1"},
100+
order: []string{"ft:feature2", "ft:feature1"},
101101
fillNa: []int64{-1},
102102
},
103103
want: nil,
@@ -107,12 +107,12 @@ func TestOnlineFeaturesResponseToInt64Array(t *testing.T) {
107107
{
108108
name: "length mismatch",
109109
args: args{
110-
order: []string{"project1/feature2", "project1/feature3"},
110+
order: []string{"featuretable1:feature2", "featuretable1:feature3"},
111111
fillNa: []int64{-1, -1},
112112
},
113113
want: nil,
114114
wantErr: true,
115-
err: fmt.Errorf(ErrFeatureNotFound, "project1/feature3"),
115+
err: fmt.Errorf(ErrFeatureNotFound, "featuretable1:feature3"),
116116
},
117117
}
118118
for _, tc := range tt {

0 commit comments

Comments
 (0)