GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — feat: Add optional 'org' in feature view (#6288) by nquinn408 · Pull Request #6301 · feast-dev/feast

feat: Add optional 'org' in feature view (#6288) #6301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Sign up for GitHub

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
nquinn408 merged 11 commits into feast-dev:master from nquinn408:add-optional-org
Apr 28, 2026

Uh oh!

There was an error while loading. Please reload this page.

Merged

feat: Add optional 'org' in feature view (#6288) #6301

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
11 commits
Select commit Hold shift + click to select a range
481f3aa
feat: Add optional 'org' in feature view (#6288)
nickquinn408 Apr 20, 2026
14c44e7
Adding pyi files
nickquinn408 Apr 20, 2026
16ebc03
Adding org ot ODFV
nickquinn408 Apr 20, 2026
c046ea3
Ignore errors in overrides
nickquinn408 Apr 21, 2026
9a94a3f
Revert changes to pyproject.toml
nickquinn408 Apr 21, 2026
b15ced3
docs: document optional org field on FeatureView and OnDemandFeatureView
nickquinn408 Apr 25, 2026
9530531
Merge branch 'master' into add-optional-org
nquinn408 Apr 27, 2026
63db9d5
Adding optional org to stream feature view
nickquinn408 Apr 27, 2026
c5b7c61
Adding org to decorator
nickquinn408 Apr 28, 2026
47119dd
Removing wrong files
nickquinn408 Apr 28, 2026
9113c43
Merge branch 'master' into add-optional-org
nquinn408 Apr 28, 2026
File filter
Filter by extension

Clear filters
Conversations
Failed to load comments.
Loading

Uh oh!

There was an error while loading. Please reload this page.

Jump to
Jump to file
Failed to load files.
Loading

Uh oh!

There was an error while loading. Please reload this page.

Diff view
Diff view

There are no files selected for viewing

5 changes: 4 additions & 1 deletion 5 docs/getting-started/concepts/feature-view.md
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Feature views consist of:
* a name to uniquely identify this feature view in the project.
* (optional, but recommended) a schema specifying one or more [features](feature-view.md#field) (without this, Feast will infer the schema by reading from the data source)
* (optional, but recommended) metadata (for example, description, or other free-form metadata via `tags`)
* (optional) `owner`: the email of the primary maintainer
* (optional) `org`: the organizational unit that owns the feature view (e.g. `"ads"`, `"search"`); useful for grouping feature views by team or product area
* (optional) a TTL, which limits how far back Feast will look when generating historical datasets
* (optional) `enable_validation=True`, which enables schema validation during materialization (see [Schema Validation](#schema-validation) below)

Expand Down Expand Up @@ -270,7 +272,7 @@ def transformed_conv_rate(features_df: pd.DataFrame) -> pd.DataFrame:

A stream feature view is an extension of a normal feature view. The primary difference is that stream feature views have both stream and batch data sources, whereas a normal feature view only has a batch data source.

Stream feature views should be used instead of normal feature views when there are stream data sources (e.g. Kafka and Kinesis) available to provide fresh features in an online setting. Here is an example definition of a stream feature view with an attached transformation:
Stream feature views should be used instead of normal feature views when there are stream data sources (e.g. Kafka and Kinesis) available to provide fresh features in an online setting. Like regular feature views, stream feature views support the optional `org` field for grouping by organizational unit. Here is an example definition of a stream feature view with an attached transformation:

```python
from datetime import timedelta
Expand Down Expand Up @@ -308,6 +310,7 @@ driver_stats_stream_source = KafkaSource(
timestamp_field="event_timestamp",
online=True,
source=driver_stats_stream_source,
org="ads", # optional
)
def driver_hourly_stats_stream(df: DataFrame):
from pyspark.sql.functions import col
Expand Down
5 changes: 4 additions & 1 deletion 5 protos/feast/core/FeatureView.proto
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ message FeatureView {
FeatureViewMeta meta = 2;
}

// Next available id: 19
// Next available id: 20
// TODO(adchia): refactor common fields from this and ODFV into separate metadata proto
message FeatureViewSpec {
// Name of the feature view. Must be unique. Not updated.
Expand Down Expand Up @@ -97,6 +97,9 @@ message FeatureViewSpec {

// User-specified version pin (e.g. "latest", "v2", "version2")
string version = 18;

// Organizational unit that owns this feature view (e.g. "ads", "search").
string org = 19;
}

message FeatureViewMeta {
Expand Down
5 changes: 4 additions & 1 deletion 5 protos/feast/core/OnDemandFeatureView.proto
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ message OnDemandFeatureView {
OnDemandFeatureViewMeta meta = 2;
}

// Next available id: 18
// Next available id: 19
message OnDemandFeatureViewSpec {
// Name of the feature view. Must be unique. Not updated.
string name = 1;
Expand Down Expand Up @@ -77,6 +77,9 @@ message OnDemandFeatureViewSpec {

// User-specified version pin (e.g. "latest", "v2", "version2")
string version = 17;

// Organizational unit that owns this feature view (e.g. "ads", "search").
string org = 18;
}

message OnDemandFeatureViewMeta {
Expand Down
5 changes: 4 additions & 1 deletion 5 protos/feast/core/StreamFeatureView.proto
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ message StreamFeatureView {
FeatureViewMeta meta = 2;
}

// Next available id: 22
// Next available id: 23
message StreamFeatureViewSpec {
// Name of the feature view. Must be unique. Not updated.
string name = 1;
Expand Down Expand Up @@ -105,5 +105,8 @@ message StreamFeatureViewSpec {

// User-specified version pin (e.g. "latest", "v2", "version2")
string version = 21;

// Organizational unit that owns this stream feature view (e.g. "ads", "search").
string org = 22;
}

4 changes: 4 additions & 0 deletions 4 sdk/python/feast/batch_feature_view.py
Show comments
View file
Open in desktop
Comment thread
nquinn408 marked this conversation as resolved.
Resolved

Uh oh!

There was an error while loading. Please reload this page.

Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def __init__(
offline: bool = False,
description: str = "",
owner: str = "",
org: str = "",
schema: Optional[List[Field]] = None,
udf: Optional[Callable[[Any], Any]] = None,
udf_string: Optional[str] = "",
Expand Down Expand Up @@ -151,6 +152,7 @@ def __init__(
offline=offline,
description=description,
owner=owner,
org=org,
schema=schema,
source=source, # type: ignore[arg-type]
sink_source=sink_source,
Expand Down Expand Up @@ -189,6 +191,7 @@ def batch_feature_view(
offline: bool = True,
description: str = "",
owner: str = "",
org: str = "",
schema: Optional[List[Field]] = None,
enable_validation: bool = False,
version: str = "latest",
Expand Down Expand Up @@ -219,6 +222,7 @@ def decorator(user_function):
offline=offline,
description=description,
owner=owner,
org=org,
schema=schema,
udf=user_function,
udf_string=udf_string,
Expand Down
12 changes: 12 additions & 0 deletions 12 sdk/python/feast/feature_view.py
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ class FeatureView(BaseFeatureView):
tags: A dictionary of key-value pairs to store arbitrary metadata.
owner: The owner of the feature view, typically the email of the primary
maintainer.
org: The organizational unit that owns this feature view (e.g. "ads", "search").
Defaults to empty string.
mode: The transformation mode for feature transformations. Only meaningful when
transformations are applied. Choose from TransformationMode enum values
(e.g., PYTHON, PANDAS, RAY, SQL, SPARK, SUBSTRAIT).
Expand All @@ -107,6 +109,7 @@ class FeatureView(BaseFeatureView):
description: str
tags: Dict[str, str]
owner: str
org: str
materialization_intervals: List[Tuple[datetime, datetime]]
mode: Optional[Union["TransformationMode", str]]
enable_validation: bool
Expand All @@ -125,6 +128,7 @@ def __init__(
description: str = "",
tags: Optional[Dict[str, str]] = None,
owner: str = "",
org: str = "",
mode: Optional[Union["TransformationMode", str]] = None,
enable_validation: bool = False,
version: str = "latest",
Expand Down Expand Up @@ -152,6 +156,8 @@ def __init__(
tags (optional): A dictionary of key-value pairs to store arbitrary metadata.
owner (optional): The owner of the feature view, typically the email of the
primary maintainer.
org (optional): The organizational unit that owns this feature view
(e.g. "ads", "search").
mode (optional): The transformation mode for feature transformations. Only meaningful
when transformations are applied. Choose from TransformationMode enum values.
enable_validation (optional): If True, enables schema validation during materialization
Expand Down Expand Up @@ -278,6 +284,7 @@ def __init__(
owner=owner,
source=self.batch_source,
)
self.org = org
self.online = online
self.offline = offline
self.mode = mode
Expand All @@ -302,6 +309,7 @@ def __copy__(self):
version=self.version,
description=self.description,
owner=self.owner,
org=self.org,
)

# This is deliberately set outside of the FV initialization as we do not have the Entity objects.
Expand Down Expand Up @@ -355,6 +363,7 @@ def __eq__(self, other):
or self.enable_validation != other.enable_validation
or normalize_version_string(self.version)
!= normalize_version_string(other.version)
or self.org != other.org
):
return False

Expand Down Expand Up @@ -485,6 +494,7 @@ def to_proto_spec(
description=self.description,
tags=self.tags,
owner=self.owner,
org=self.org,
ttl=(ttl_duration if ttl_duration is not None else None),
online=self.online,
offline=self.offline,
Expand Down Expand Up @@ -615,6 +625,7 @@ def _from_proto_internal(
description=feature_view_proto.spec.description,
tags=dict(feature_view_proto.spec.tags),
owner=feature_view_proto.spec.owner,
org=feature_view_proto.spec.org,
online=feature_view_proto.spec.online,
offline=feature_view_proto.spec.offline,
ttl=(
Expand All @@ -637,6 +648,7 @@ def _from_proto_internal(
description=feature_view_proto.spec.description,
tags=dict(feature_view_proto.spec.tags),
owner=feature_view_proto.spec.owner,
org=feature_view_proto.spec.org,
online=feature_view_proto.spec.online,
offline=feature_view_proto.spec.offline,
ttl=(
Expand Down
15 changes: 15 additions & 0 deletions 15 sdk/python/feast/on_demand_feature_view.py
Show comments
View file
Open in desktop
Comment thread
nquinn408 marked this conversation as resolved.
Resolved

Uh oh!

There was an error while loading. Please reload this page.

Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ class OnDemandFeatureView(BaseFeatureView):
tags: A dictionary of key-value pairs to store arbitrary metadata.
owner: The owner of the on demand feature view, typically the email of the primary
maintainer.
org: The organizational unit that owns this on demand feature view (e.g. "ads",
"search"). Defaults to empty string.
Comment thread
nquinn408 marked this conversation as resolved.
Resolved

Uh oh!

There was an error while loading. Please reload this page.

"""

_TRACK_METRICS_TAG = "feast:track_metrics"
Expand All @@ -146,6 +148,7 @@ class OnDemandFeatureView(BaseFeatureView):
description: str
tags: dict[str, str]
owner: str
org: str
write_to_online_store: bool
singleton: bool
track_metrics: bool
Expand All @@ -168,6 +171,7 @@ def __init__( # noqa: C901
description: str = "",
tags: Optional[dict[str, str]] = None,
owner: str = "",
org: str = "",
write_to_online_store: bool = False,
singleton: bool = False,
track_metrics: bool = False,
Expand Down Expand Up @@ -199,6 +203,8 @@ def __init__( # noqa: C901
tags (optional): A dictionary of key-value pairs to store arbitrary metadata.
owner (optional): The owner of the on demand feature view, typically the email
of the primary maintainer.
org (optional): The organizational unit that owns this feature view
(e.g. "ads", "search").
write_to_online_store (optional): A boolean that indicates whether to write the on demand feature view to
the online store for faster retrieval.
singleton (optional): A boolean that indicates whether the transformation is executed on a singleton
Expand All @@ -218,6 +224,7 @@ def __init__( # noqa: C901
owner=owner,
)

self.org = org
self.version = version
schema = schema or []
self.entities = [e.name for e in entities] if entities else [DUMMY_ENTITY_NAME]
Expand Down Expand Up @@ -384,6 +391,7 @@ def __copy__(self):
description=self.description,
tags=self.tags,
owner=self.owner,
org=self.org,
write_to_online_store=self.write_to_online_store,
singleton=self.singleton,
version=self.version,
Expand Down Expand Up @@ -463,6 +471,7 @@ def __eq__(self, other):
or self.aggregations != other.aggregations
or normalize_version_string(self.version)
!= normalize_version_string(other.version)
or self.org != other.org
):
return False

Expand Down Expand Up @@ -621,6 +630,7 @@ def to_proto(self) -> OnDemandFeatureViewProto:
description=self.description,
tags=tags,
owner=self.owner,
org=self.org,
write_to_online_store=self.write_to_online_store,
singleton=self.singleton or False,
aggregations=[agg.to_proto() for agg in self.aggregations],
Expand Down Expand Up @@ -689,6 +699,7 @@ def from_proto(
description=on_demand_feature_view_proto.spec.description,
tags=proto_tags,
owner=on_demand_feature_view_proto.spec.owner,
org=on_demand_feature_view_proto.spec.org,
write_to_online_store=optional_fields["write_to_online_store"],
singleton=optional_fields["singleton"],
track_metrics=track_metrics,
Expand Down Expand Up @@ -1336,6 +1347,7 @@ def on_demand_feature_view(
description: str = "",
tags: Optional[dict[str, str]] = None,
owner: str = "",
org: str = "",
write_to_online_store: bool = False,
singleton: bool = False,
track_metrics: bool = False,
Expand All @@ -1362,6 +1374,8 @@ def on_demand_feature_view(
tags (optional): A dictionary of key-value pairs to store arbitrary metadata.
owner (optional): The owner of the on demand feature view, typically the email
of the primary maintainer.
org (optional): The organizational unit that owns this on demand feature view
(e.g. "ads", "search"). Defaults to empty string.
write_to_online_store (optional): A boolean that indicates whether to write the on demand feature view to
the online store for faster retrieval.
singleton (optional): A boolean that indicates whether the transformation is executed on a singleton
Expand Down Expand Up @@ -1390,6 +1404,7 @@ def decorator(user_function):
description=description,
tags=tags,
owner=owner,
org=org,
write_to_online_store=write_to_online_store,
entities=entities,
singleton=singleton,
Expand Down
65 changes: 35 additions & 30 deletions 65 sdk/python/feast/protos/feast/core/Aggregation_pb2.pyi
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,49 @@
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
"""
import builtins
import google.protobuf.descriptor
import google.protobuf.duration_pb2
import google.protobuf.message

from google.protobuf import descriptor as _descriptor
from google.protobuf import duration_pb2 as _duration_pb2
from google.protobuf import message as _message
import builtins as _builtins
import sys
import typing as _typing

if sys.version_info >= (3, 8):
import typing as typing_extensions
if sys.version_info >= (3, 10):
from typing import TypeAlias as _TypeAlias
else:
import typing_extensions
from typing_extensions import TypeAlias as _TypeAlias

DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
DESCRIPTOR: _descriptor.FileDescriptor

class Aggregation(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
@_typing.final
class Aggregation(_message.Message):
DESCRIPTOR: _descriptor.Descriptor

COLUMN_FIELD_NUMBER: builtins.int
FUNCTION_FIELD_NUMBER: builtins.int
TIME_WINDOW_FIELD_NUMBER: builtins.int
SLIDE_INTERVAL_FIELD_NUMBER: builtins.int
NAME_FIELD_NUMBER: builtins.int
column: builtins.str
function: builtins.str
@property
def time_window(self) -> google.protobuf.duration_pb2.Duration: ...
@property
def slide_interval(self) -> google.protobuf.duration_pb2.Duration: ...
name: builtins.str
COLUMN_FIELD_NUMBER: _builtins.int
FUNCTION_FIELD_NUMBER: _builtins.int
TIME_WINDOW_FIELD_NUMBER: _builtins.int
SLIDE_INTERVAL_FIELD_NUMBER: _builtins.int
NAME_FIELD_NUMBER: _builtins.int
column: _builtins.str
function: _builtins.str
name: _builtins.str
@_builtins.property
def time_window(self) -> _duration_pb2.Duration: ...
@_builtins.property
def slide_interval(self) -> _duration_pb2.Duration: ...
def __init__(
self,
*,
column: builtins.str = ...,
function: builtins.str = ...,
time_window: google.protobuf.duration_pb2.Duration | None = ...,
slide_interval: google.protobuf.duration_pb2.Duration | None = ...,
name: builtins.str = ...,
column: _builtins.str = ...,
function: _builtins.str = ...,
time_window: _duration_pb2.Duration | None = ...,
slide_interval: _duration_pb2.Duration | None = ...,
name: _builtins.str = ...,
) -> None: ...
def HasField(self, field_name: typing_extensions.Literal["slide_interval", b"slide_interval", "time_window", b"time_window"]) -> builtins.bool: ...
def ClearField(self, field_name: typing_extensions.Literal["column", b"column", "function", b"function", "name", b"name", "slide_interval", b"slide_interval", "time_window", b"time_window"]) -> None: ...
_HasFieldArgType: _TypeAlias = _typing.Literal["slide_interval", b"slide_interval", "time_window", b"time_window"] # noqa: Y015
def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ...
_ClearFieldArgType: _TypeAlias = _typing.Literal["column", b"column", "function", b"function", "name", b"name", "slide_interval", b"slide_interval", "time_window", b"time_window"] # noqa: Y015
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...

global___Aggregation = Aggregation
Global___Aggregation: _TypeAlias = Aggregation # noqa: Y015
Loading
Oops, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Loading
Oops, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.