Skip to content

Commit fbf92da

Browse files
authored
feat: Add the ability to list objects by tags (feast-dev#4246)
add tags filtering capability to 'list' for objects Signed-off-by: Tommy Hughes <[email protected]>
1 parent 7287662 commit fbf92da

File tree

21 files changed

+629
-169
lines changed

21 files changed

+629
-169
lines changed

docs/reference/feast-cli-commands.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ List all registered entities
6666

6767
```text
6868
feast entities list
69+
70+
Options:
71+
--tags TEXT Filter by tags (e.g. --tags 'key:value' --tags 'key:value,
72+
key:value, ...'). Items return when ALL tags match.
6973
```
7074

7175
```text
@@ -79,11 +83,15 @@ List all registered feature views
7983

8084
```text
8185
feast feature-views list
86+
87+
Options:
88+
--tags TEXT Filter by tags (e.g. --tags 'key:value' --tags 'key:value,
89+
key:value, ...'). Items return when ALL tags match.
8290
```
8391

8492
```text
85-
NAME ENTITIES
86-
driver_hourly_stats ['driver_id']
93+
NAME ENTITIES TYPE
94+
driver_hourly_stats {'driver'} FeatureView
8795
```
8896

8997
## Init

protos/feast/registry/RegistryServer.proto

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ message GetEntityRequest {
117117
message ListEntitiesRequest {
118118
string project = 1;
119119
bool allow_cache = 2;
120+
map<string,string> tags = 3;
120121
}
121122

122123
message ListEntitiesResponse {
@@ -146,6 +147,7 @@ message GetDataSourceRequest {
146147
message ListDataSourcesRequest {
147148
string project = 1;
148149
bool allow_cache = 2;
150+
map<string,string> tags = 3;
149151
}
150152

151153
message ListDataSourcesResponse {
@@ -179,6 +181,7 @@ message GetFeatureViewRequest {
179181
message ListFeatureViewsRequest {
180182
string project = 1;
181183
bool allow_cache = 2;
184+
map<string,string> tags = 3;
182185
}
183186

184187
message ListFeatureViewsResponse {
@@ -202,6 +205,7 @@ message GetStreamFeatureViewRequest {
202205
message ListStreamFeatureViewsRequest {
203206
string project = 1;
204207
bool allow_cache = 2;
208+
map<string,string> tags = 3;
205209
}
206210

207211
message ListStreamFeatureViewsResponse {
@@ -219,6 +223,7 @@ message GetOnDemandFeatureViewRequest {
219223
message ListOnDemandFeatureViewsRequest {
220224
string project = 1;
221225
bool allow_cache = 2;
226+
map<string,string> tags = 3;
222227
}
223228

224229
message ListOnDemandFeatureViewsResponse {
@@ -242,6 +247,7 @@ message GetFeatureServiceRequest {
242247
message ListFeatureServicesRequest {
243248
string project = 1;
244249
bool allow_cache = 2;
250+
map<string,string> tags = 3;
245251
}
246252

247253
message ListFeatureServicesResponse {

sdk/python/feast/cli.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@
4747
from feast.utils import maybe_local_tz
4848

4949
_logger = logging.getLogger(__name__)
50+
tagsOption = click.option(
51+
"--tags",
52+
help="Filter by tags (e.g. --tags 'key:value' --tags 'key:value, key:value, ...'). Items return when ALL tags match.",
53+
default=[""],
54+
multiple=True,
55+
)
5056

5157

5258
class NoOptionDefaultFormat(click.Command):
@@ -226,14 +232,16 @@ def data_source_describe(ctx: click.Context, name: str):
226232

227233

228234
@data_sources_cmd.command(name="list")
235+
@tagsOption
229236
@click.pass_context
230-
def data_source_list(ctx: click.Context):
237+
def data_source_list(ctx: click.Context, tags: list[str]):
231238
"""
232239
List all data sources
233240
"""
234241
store = create_feature_store(ctx)
235242
table = []
236-
for datasource in store.list_data_sources():
243+
tags_filter = utils.tags_list_to_dict(tags)
244+
for datasource in store.list_data_sources(tags=tags_filter):
237245
table.append([datasource.name, datasource.__class__])
238246

239247
from tabulate import tabulate
@@ -272,14 +280,16 @@ def entity_describe(ctx: click.Context, name: str):
272280

273281

274282
@entities_cmd.command(name="list")
283+
@tagsOption
275284
@click.pass_context
276-
def entity_list(ctx: click.Context):
285+
def entity_list(ctx: click.Context, tags: list[str]):
277286
"""
278287
List all entities
279288
"""
280289
store = create_feature_store(ctx)
281290
table = []
282-
for entity in store.list_entities():
291+
tags_filter = utils.tags_list_to_dict(tags)
292+
for entity in store.list_entities(tags=tags_filter):
283293
table.append([entity.name, entity.description, entity.value_type])
284294

285295
from tabulate import tabulate
@@ -320,14 +330,16 @@ def feature_service_describe(ctx: click.Context, name: str):
320330

321331

322332
@feature_services_cmd.command(name="list")
333+
@tagsOption
323334
@click.pass_context
324-
def feature_service_list(ctx: click.Context):
335+
def feature_service_list(ctx: click.Context, tags: list[str]):
325336
"""
326337
List all feature services
327338
"""
328339
store = create_feature_store(ctx)
329340
feature_services = []
330-
for feature_service in store.list_feature_services():
341+
tags_filter = utils.tags_list_to_dict(tags)
342+
for feature_service in store.list_feature_services(tags=tags_filter):
331343
feature_names = []
332344
for projection in feature_service.feature_view_projections:
333345
feature_names.extend(
@@ -371,16 +383,18 @@ def feature_view_describe(ctx: click.Context, name: str):
371383

372384

373385
@feature_views_cmd.command(name="list")
386+
@tagsOption
374387
@click.pass_context
375-
def feature_view_list(ctx: click.Context):
388+
def feature_view_list(ctx: click.Context, tags: list[str]):
376389
"""
377390
List all feature views
378391
"""
379392
store = create_feature_store(ctx)
380393
table = []
394+
tags_filter = utils.tags_list_to_dict(tags)
381395
for feature_view in [
382-
*store.list_feature_views(),
383-
*store.list_on_demand_feature_views(),
396+
*store.list_batch_feature_views(tags=tags_filter),
397+
*store.list_on_demand_feature_views(tags=tags_filter),
384398
]:
385399
entities = set()
386400
if isinstance(feature_view, FeatureView):
@@ -434,14 +448,16 @@ def on_demand_feature_view_describe(ctx: click.Context, name: str):
434448

435449

436450
@on_demand_feature_views_cmd.command(name="list")
451+
@tagsOption
437452
@click.pass_context
438-
def on_demand_feature_view_list(ctx: click.Context):
453+
def on_demand_feature_view_list(ctx: click.Context, tags: list[str]):
439454
"""
440455
[Experimental] List all on demand feature views
441456
"""
442457
store = create_feature_store(ctx)
443458
table = []
444-
for on_demand_feature_view in store.list_on_demand_feature_views():
459+
tags_filter = utils.tags_list_to_dict(tags)
460+
for on_demand_feature_view in store.list_on_demand_feature_views(tags=tags_filter):
445461
table.append([on_demand_feature_view.name])
446462

447463
from tabulate import tabulate

0 commit comments

Comments
 (0)