Skip to content

Commit 373e624

Browse files
authored
feat: Add gRPC Registry Server (#3924)
1 parent 1f3cab8 commit 373e624

File tree

9 files changed

+532
-5
lines changed

9 files changed

+532
-5
lines changed
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
syntax = "proto3";
2+
3+
package feast.registry;
4+
5+
import "google/protobuf/timestamp.proto";
6+
import "google/protobuf/empty.proto";
7+
import "feast/core/Registry.proto";
8+
import "feast/core/Entity.proto";
9+
import "feast/core/DataSource.proto";
10+
import "feast/core/FeatureView.proto";
11+
import "feast/core/RequestFeatureView.proto";
12+
import "feast/core/StreamFeatureView.proto";
13+
import "feast/core/OnDemandFeatureView.proto";
14+
import "feast/core/FeatureService.proto";
15+
import "feast/core/SavedDataset.proto";
16+
import "feast/core/ValidationProfile.proto";
17+
import "feast/core/InfraObject.proto";
18+
19+
service RegistryServer{
20+
// Entity RPCs
21+
rpc GetEntity (GetEntityRequest) returns (feast.core.Entity) {}
22+
rpc ListEntities (ListEntitiesRequest) returns (ListEntitiesResponse) {}
23+
24+
// DataSource RPCs
25+
rpc GetDataSource (GetDataSourceRequest) returns (feast.core.DataSource) {}
26+
rpc ListDataSources (ListDataSourcesRequest) returns (ListDataSourcesResponse) {}
27+
28+
// FeatureView RPCs
29+
rpc GetFeatureView (GetFeatureViewRequest) returns (feast.core.FeatureView) {}
30+
rpc ListFeatureViews (ListFeatureViewsRequest) returns (ListFeatureViewsResponse) {}
31+
32+
// RequestFeatureView RPCs
33+
rpc GetRequestFeatureView (GetRequestFeatureViewRequest) returns (feast.core.RequestFeatureView) {}
34+
rpc ListRequestFeatureViews (ListRequestFeatureViewsRequest) returns (ListRequestFeatureViewsResponse) {}
35+
36+
// StreamFeatureView RPCs
37+
rpc GetStreamFeatureView (GetStreamFeatureViewRequest) returns (feast.core.StreamFeatureView) {}
38+
rpc ListStreamFeatureViews (ListStreamFeatureViewsRequest) returns (ListStreamFeatureViewsResponse) {}
39+
40+
// OnDemandFeatureView RPCs
41+
rpc GetOnDemandFeatureView (GetOnDemandFeatureViewRequest) returns (feast.core.OnDemandFeatureView) {}
42+
rpc ListOnDemandFeatureViews (ListOnDemandFeatureViewsRequest) returns (ListOnDemandFeatureViewsResponse) {}
43+
44+
// FeatureService RPCs
45+
rpc GetFeatureService (GetFeatureServiceRequest) returns (feast.core.FeatureService) {}
46+
rpc ListFeatureServices (ListFeatureServicesRequest) returns (ListFeatureServicesResponse) {}
47+
48+
// SavedDataset RPCs
49+
rpc GetSavedDataset (GetSavedDatasetRequest) returns (feast.core.SavedDataset) {}
50+
rpc ListSavedDatasets (ListSavedDatasetsRequest) returns (ListSavedDatasetsResponse) {}
51+
52+
// ValidationReference RPCs
53+
rpc GetValidationReference (GetValidationReferenceRequest) returns (feast.core.ValidationReference) {}
54+
rpc ListValidationReferences (ListValidationReferencesRequest) returns (ListValidationReferencesResponse) {}
55+
56+
rpc ListProjectMetadata (ListProjectMetadataRequest) returns (ListProjectMetadataResponse) {}
57+
rpc GetInfra (GetInfraRequest) returns (feast.core.Infra) {}
58+
rpc Refresh (RefreshRequest) returns (google.protobuf.Empty) {}
59+
rpc Proto (google.protobuf.Empty) returns (feast.core.Registry) {}
60+
61+
}
62+
63+
message RefreshRequest {
64+
string project = 1;
65+
}
66+
67+
message GetInfraRequest {
68+
string project = 1;
69+
bool allow_cache = 2;
70+
}
71+
72+
message ListProjectMetadataRequest {
73+
string project = 1;
74+
bool allow_cache = 2;
75+
}
76+
77+
message ListProjectMetadataResponse {
78+
repeated feast.core.ProjectMetadata project_metadata = 1;
79+
}
80+
81+
message GetEntityRequest {
82+
string name = 1;
83+
string project = 2;
84+
bool allow_cache = 3;
85+
}
86+
87+
message ListEntitiesRequest {
88+
string project = 1;
89+
bool allow_cache = 2;
90+
}
91+
92+
message ListEntitiesResponse {
93+
repeated feast.core.Entity entities = 1;
94+
}
95+
96+
// DataSources
97+
98+
message GetDataSourceRequest {
99+
string name = 1;
100+
string project = 2;
101+
bool allow_cache = 3;
102+
}
103+
104+
message ListDataSourcesRequest {
105+
string project = 1;
106+
bool allow_cache = 2;
107+
}
108+
109+
message ListDataSourcesResponse {
110+
repeated feast.core.DataSource data_sources = 1;
111+
}
112+
113+
// FeatureViews
114+
115+
message GetFeatureViewRequest {
116+
string name = 1;
117+
string project = 2;
118+
bool allow_cache = 3;
119+
}
120+
121+
message ListFeatureViewsRequest {
122+
string project = 1;
123+
bool allow_cache = 2;
124+
}
125+
126+
message ListFeatureViewsResponse {
127+
repeated feast.core.FeatureView feature_views = 1;
128+
}
129+
130+
// RequestFeatureView
131+
132+
message GetRequestFeatureViewRequest {
133+
string name = 1;
134+
string project = 2;
135+
bool allow_cache = 3;
136+
}
137+
138+
message ListRequestFeatureViewsRequest {
139+
string project = 1;
140+
bool allow_cache = 2;
141+
}
142+
143+
message ListRequestFeatureViewsResponse {
144+
repeated feast.core.RequestFeatureView request_feature_views = 1;
145+
}
146+
147+
// StreamFeatureView
148+
149+
message GetStreamFeatureViewRequest {
150+
string name = 1;
151+
string project = 2;
152+
bool allow_cache = 3;
153+
}
154+
155+
message ListStreamFeatureViewsRequest {
156+
string project = 1;
157+
bool allow_cache = 2;
158+
}
159+
160+
message ListStreamFeatureViewsResponse {
161+
repeated feast.core.StreamFeatureView stream_feature_views = 1;
162+
}
163+
164+
// OnDemandFeatureView
165+
166+
message GetOnDemandFeatureViewRequest {
167+
string name = 1;
168+
string project = 2;
169+
bool allow_cache = 3;
170+
}
171+
172+
message ListOnDemandFeatureViewsRequest {
173+
string project = 1;
174+
bool allow_cache = 2;
175+
}
176+
177+
message ListOnDemandFeatureViewsResponse {
178+
repeated feast.core.OnDemandFeatureView on_demand_feature_views = 1;
179+
}
180+
181+
// FeatureServices
182+
183+
message GetFeatureServiceRequest {
184+
string name = 1;
185+
string project = 2;
186+
bool allow_cache = 3;
187+
}
188+
189+
message ListFeatureServicesRequest {
190+
string project = 1;
191+
bool allow_cache = 2;
192+
}
193+
194+
message ListFeatureServicesResponse {
195+
repeated feast.core.FeatureService feature_services = 1;
196+
}
197+
198+
// SavedDataset
199+
200+
message GetSavedDatasetRequest {
201+
string name = 1;
202+
string project = 2;
203+
bool allow_cache = 3;
204+
}
205+
206+
message ListSavedDatasetsRequest {
207+
string project = 1;
208+
bool allow_cache = 2;
209+
}
210+
211+
message ListSavedDatasetsResponse {
212+
repeated feast.core.SavedDataset saved_datasets = 1;
213+
}
214+
215+
// ValidationReference
216+
217+
message GetValidationReferenceRequest {
218+
string name = 1;
219+
string project = 2;
220+
bool allow_cache = 3;
221+
}
222+
223+
message ListValidationReferencesRequest {
224+
string project = 1;
225+
bool allow_cache = 2;
226+
}
227+
228+
message ListValidationReferencesResponse {
229+
repeated feast.core.ValidationReference validation_references = 1;
230+
}

sdk/python/feast/cli.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@
2525
from pygments import formatters, highlight, lexers
2626

2727
from feast import utils
28-
from feast.constants import DEFAULT_FEATURE_TRANSFORMATION_SERVER_PORT
28+
from feast.constants import (
29+
DEFAULT_FEATURE_TRANSFORMATION_SERVER_PORT,
30+
DEFAULT_REGISTRY_SERVER_PORT,
31+
)
2932
from feast.errors import FeastObjectNotFoundException, FeastProviderLoginError
3033
from feast.feature_view import FeatureView
3134
from feast.infra.contrib.grpc_server import get_grpc_server
@@ -753,6 +756,22 @@ def serve_transformations_command(ctx: click.Context, port: int):
753756
store.serve_transformations(port)
754757

755758

759+
@cli.command("serve_registry")
760+
@click.option(
761+
"--port",
762+
"-p",
763+
type=click.INT,
764+
default=DEFAULT_REGISTRY_SERVER_PORT,
765+
help="Specify a port for the server",
766+
)
767+
@click.pass_context
768+
def serve_registry_command(ctx: click.Context, port: int):
769+
"""Start a registry server locally on a given port."""
770+
store = create_feature_store(ctx)
771+
772+
store.serve_registry(port)
773+
774+
756775
@cli.command("validate")
757776
@click.option(
758777
"--feature-service",

sdk/python/feast/constants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,8 @@
4444
# Default FTS port
4545
DEFAULT_FEATURE_TRANSFORMATION_SERVER_PORT = 6569
4646

47+
# Default registry server port
48+
DEFAULT_REGISTRY_SERVER_PORT = 6570
49+
4750
# Environment variable for feature server docker image tag
4851
DOCKER_IMAGE_TAG_ENV_NAME: str = "FEAST_SERVER_DOCKER_IMAGE_TAG"

sdk/python/feast/feature_store.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2278,6 +2278,13 @@ def serve_ui(
22782278
root_path=root_path,
22792279
)
22802280

2281+
@log_exceptions_and_usage
2282+
def serve_registry(self, port: int) -> None:
2283+
"""Start registry server locally on a given port."""
2284+
from feast import registry_server
2285+
2286+
registry_server.start_server(self, port)
2287+
22812288
@log_exceptions_and_usage
22822289
def serve_transformations(self, port: int) -> None:
22832290
"""Start the feature transformation server locally on a given port."""

sdk/python/feast/infra/registry/base_registry.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,9 @@ def list_feature_views(
329329

330330
# request feature view operations
331331
@abstractmethod
332-
def get_request_feature_view(self, name: str, project: str) -> RequestFeatureView:
332+
def get_request_feature_view(
333+
self, name: str, project: str, allow_cache: bool = False
334+
) -> RequestFeatureView:
333335
"""
334336
Retrieves a request feature view.
335337

sdk/python/feast/infra/registry/registry.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,8 +528,12 @@ def list_feature_views(
528528
)
529529
return proto_registry_utils.list_feature_views(registry_proto, project)
530530

531-
def get_request_feature_view(self, name: str, project: str):
532-
registry_proto = self._get_registry_proto(project=project, allow_cache=False)
531+
def get_request_feature_view(
532+
self, name: str, project: str, allow_cache: bool = False
533+
):
534+
registry_proto = self._get_registry_proto(
535+
project=project, allow_cache=allow_cache
536+
)
533537
return proto_registry_utils.get_request_feature_view(
534538
registry_proto, name, project
535539
)

0 commit comments

Comments
 (0)