Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ exclude = '''
| pb2.py
| \.pyi
| protos
| sdk/python/feast/embedded_go/lib
)/
)
'''
30 changes: 23 additions & 7 deletions sdk/python/feast/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,10 @@ def registry_dump_command(ctx: click.Context):
@click.argument("start_ts")
@click.argument("end_ts")
@click.option(
"--views", "-v", help="Feature views to materialize", multiple=True,
"--views",
"-v",
help="Feature views to materialize",
multiple=True,
)
@click.pass_context
def materialize_command(
Expand All @@ -551,7 +554,10 @@ def materialize_command(
@cli.command("materialize-incremental")
@click.argument("end_ts")
@click.option(
"--views", "-v", help="Feature views to incrementally materialize", multiple=True,
"--views",
"-v",
help="Feature views to incrementally materialize",
multiple=True,
)
@click.pass_context
def materialize_incremental_command(ctx: click.Context, end_ts: str, views: List[str]):
Expand Down Expand Up @@ -622,10 +628,14 @@ def init_command(project_directory, minimal: bool, template: str):
help="Specify a server type: 'http' or 'grpc' [default: http]",
)
@click.option(
"--no-access-log", is_flag=True, help="Disable the Uvicorn access log.",
"--no-access-log",
is_flag=True,
help="Disable the Uvicorn access log.",
)
@click.option(
"--no-feature-log", is_flag=True, help="Disable logging served features",
"--no-feature-log",
is_flag=True,
help="Disable logging served features",
)
@click.pass_context
def serve_command(
Expand Down Expand Up @@ -771,13 +781,19 @@ def disable_alpha_features(ctx: click.Context):

@cli.command("validate")
@click.option(
"--feature-service", "-f", help="Specify a feature service name",
"--feature-service",
"-f",
help="Specify a feature service name",
)
@click.option(
"--reference", "-r", help="Specify a validation reference name",
"--reference",
"-r",
help="Specify a validation reference name",
)
@click.option(
"--no-profile-cache", is_flag=True, help="Do not store cached profile in registry",
"--no-profile-cache",
is_flag=True,
help="Do not store cached profile in registry",
)
@click.argument("start_ts")
@click.argument("end_ts")
Expand Down
5 changes: 4 additions & 1 deletion sdk/python/feast/data_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ class KinesisOptions:
"""

def __init__(
self, record_format: StreamFormat, region: str, stream_name: str,
self,
record_format: StreamFormat,
region: str,
stream_name: str,
):
self.record_format = record_format
self.region = region
Expand Down
10 changes: 8 additions & 2 deletions sdk/python/feast/diff/infra_diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ def diff_infra_protos(
infra_objects_to_delete,
infra_objects_to_add,
) = tag_infra_proto_objects_for_keep_delete_add(
current_infra_objects, new_infra_objects,
current_infra_objects,
new_infra_objects,
)

for e in infra_objects_to_add:
Expand Down Expand Up @@ -199,5 +200,10 @@ def diff_between(
)
)
return InfraObjectDiff(
new.name, infra_object_type, current, new, property_diffs, transition,
new.name,
infra_object_type,
current,
new,
property_diffs,
transition,
)
16 changes: 12 additions & 4 deletions sdk/python/feast/diff/registry_diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@ def diff_registry_objects(


def extract_objects_for_keep_delete_update_add(
registry: BaseRegistry, current_project: str, desired_repo_contents: RepoContents,
registry: BaseRegistry,
current_project: str,
desired_repo_contents: RepoContents,
) -> Tuple[
Dict[FeastObjectType, Set[FeastObject]],
Dict[FeastObjectType, Set[FeastObject]],
Expand Down Expand Up @@ -208,7 +210,9 @@ def extract_objects_for_keep_delete_update_add(


def diff_between(
registry: BaseRegistry, current_project: str, desired_repo_contents: RepoContents,
registry: BaseRegistry,
current_project: str,
desired_repo_contents: RepoContents,
) -> RegistryDiff:
"""
Returns the difference between the current and desired repo states.
Expand Down Expand Up @@ -305,12 +309,16 @@ def apply_diff_to_registry(
BaseFeatureView, feast_object_diff.current_feast_object
)
registry.delete_feature_view(
feature_view_obj.name, project, commit=False,
feature_view_obj.name,
project,
commit=False,
)
elif feast_object_diff.feast_object_type == FeastObjectType.DATA_SOURCE:
ds_obj = cast(DataSource, feast_object_diff.current_feast_object)
registry.delete_data_source(
ds_obj.name, project, commit=False,
ds_obj.name,
project,
commit=False,
)

if feast_object_diff.transition_type in [
Expand Down
7 changes: 6 additions & 1 deletion sdk/python/feast/driver_test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ def _convert_event_timestamp(event_timestamp: pd.Timestamp, t: EventTimestampTyp


def create_orders_df(
customers, drivers, start_date, end_date, order_count, locations=None,
customers,
drivers,
start_date,
end_date,
order_count,
locations=None,
) -> pd.DataFrame:
"""
Example df generated by this function (if locations):
Expand Down
7 changes: 5 additions & 2 deletions sdk/python/feast/embedded_go/online_features_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ def __init__(
)

self._service = NewOnlineFeatureService(
self._config, self._transformation_callback,
self._config,
self._transformation_callback,
)

# This should raise an exception if there were any errors in NewOnlineFeatureService.
Expand Down Expand Up @@ -263,7 +264,9 @@ def transformation_callback(


def logging_callback(
fs: "FeatureStore", feature_service_name: str, dataset_dir: str,
fs: "FeatureStore",
feature_service_name: str,
dataset_dir: str,
) -> bytes:
feature_service = fs.get_feature_service(feature_service_name, allow_cache=True)
try:
Expand Down
9 changes: 7 additions & 2 deletions sdk/python/feast/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ class Feature:
"""

def __init__(
self, name: str, dtype: ValueType, labels: Optional[Dict[str, str]] = None,
self,
name: str,
dtype: ValueType,
labels: Optional[Dict[str, str]] = None,
):
"""Creates a Feature object."""
self._name = name
Expand Down Expand Up @@ -91,7 +94,9 @@ def to_proto(self) -> FeatureSpecProto:
value_type = ValueTypeProto.Enum.Value(self.dtype.name)

return FeatureSpecProto(
name=self.name, value_type=value_type, tags=self.labels,
name=self.name,
value_type=value_type,
tags=self.labels,
)

@classmethod
Expand Down
4 changes: 2 additions & 2 deletions sdk/python/feast/feature_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ class LoggingSource:

@abc.abstractmethod
def get_schema(self, registry: "BaseRegistry") -> pa.Schema:
""" Generate schema for logs destination. """
"""Generate schema for logs destination."""
raise NotImplementedError

@abc.abstractmethod
def get_log_timestamp_column(self) -> str:
""" Return timestamp column that must exist in generated schema. """
"""Return timestamp column that must exist in generated schema."""
raise NotImplementedError


Expand Down
66 changes: 45 additions & 21 deletions sdk/python/feast/feature_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ class FeatureStore:

@log_exceptions
def __init__(
self, repo_path: Optional[str] = None, config: Optional[RepoConfig] = None,
self,
repo_path: Optional[str] = None,
config: Optional[RepoConfig] = None,
):
"""
Creates a FeatureStore object.
Expand Down Expand Up @@ -253,7 +255,9 @@ def list_request_feature_views(
)

def _list_feature_views(
self, allow_cache: bool = False, hide_dummy_entity: bool = True,
self,
allow_cache: bool = False,
hide_dummy_entity: bool = True,
) -> List[FeatureView]:
feature_views = []
for fv in self._registry.list_feature_views(
Expand All @@ -266,7 +270,9 @@ def _list_feature_views(
return feature_views

def _list_stream_feature_views(
self, allow_cache: bool = False, hide_dummy_entity: bool = True,
self,
allow_cache: bool = False,
hide_dummy_entity: bool = True,
) -> List[StreamFeatureView]:
stream_feature_views = []
for sfv in self._registry.list_stream_feature_views(
Expand Down Expand Up @@ -480,7 +486,9 @@ def delete_feature_service(self, name: str):
return self._registry.delete_feature_service(name, self.project)

def _get_features(
self, features: Union[List[str], FeatureService], allow_cache: bool = False,
self,
features: Union[List[str], FeatureService],
allow_cache: bool = False,
) -> List[str]:
_features = features

Expand Down Expand Up @@ -589,7 +597,8 @@ def _make_inferences(
feature_service.infer_features(fvs_to_update=fvs_to_update_map)

def _get_feature_views_to_materialize(
self, feature_views: Optional[List[str]],
self,
feature_views: Optional[List[str]],
) -> List[FeatureView]:
"""
Returns the list of feature views that should be materialized.
Expand Down Expand Up @@ -1069,7 +1078,8 @@ def get_historical_features(
for feature_name in odfv_request_data_schema.keys():
if feature_name not in entity_df.columns:
raise RequestDataNotFoundInEntityDfException(
feature_name=feature_name, feature_view_name=odfv.name,
feature_name=feature_name,
feature_view_name=odfv.name,
)

_validate_feature_refs(_feature_refs, full_feature_names)
Expand Down Expand Up @@ -1182,7 +1192,9 @@ def get_saved_dataset(self, name: str) -> SavedDataset:

@log_exceptions_and_usage
def materialize_incremental(
self, end_date: datetime, feature_views: Optional[List[str]] = None,
self,
end_date: datetime,
feature_views: Optional[List[str]] = None,
) -> None:
"""
Materialize incremental new data from the offline store into the online store.
Expand Down Expand Up @@ -1264,7 +1276,10 @@ def tqdm_builder(length):
)

self._registry.apply_materialization(
feature_view, self.project, start_date, end_date,
feature_view,
self.project,
start_date,
end_date,
)

@log_exceptions_and_usage
Expand Down Expand Up @@ -1336,7 +1351,10 @@ def tqdm_builder(length):
)

self._registry.apply_materialization(
feature_view, self.project, start_date, end_date,
feature_view,
self.project,
start_date,
end_date,
)

@log_exceptions_and_usage
Expand Down Expand Up @@ -1439,8 +1457,8 @@ def write_to_offline_store(
)

# Get columns of the batch source and the input dataframe.
column_names_and_types = feature_view.batch_source.get_table_column_names_and_types(
self.config
column_names_and_types = (
feature_view.batch_source.get_table_column_names_and_types(self.config)
)
source_columns = [column for column, _ in column_names_and_types]
input_columns = df.columns.values.tolist()
Expand Down Expand Up @@ -1701,12 +1719,17 @@ def _get_online_features(
for table, requested_features in grouped_refs:
# Get the correct set of entity values with the correct join keys.
table_entity_values, idxs = self._get_unique_entities(
table, join_key_values, entity_name_to_join_key_map,
table,
join_key_values,
entity_name_to_join_key_map,
)

# Fetch feature data for the minimum set of Entities.
feature_data = self._read_from_online_store(
table_entity_values, provider, requested_features, table,
table_entity_values,
provider,
requested_features,
table,
)

# Populate the result_rows with the Features from the OnlineStore inplace.
Expand Down Expand Up @@ -1875,7 +1898,9 @@ def _get_unique_entities(
"""
# Get the correct set of entity values with the correct join keys.
table_entity_values = self._get_table_entity_values(
table, entity_name_to_join_key_map, join_key_values,
table,
entity_name_to_join_key_map,
join_key_values,
)

# Convert back to rowise.
Expand Down Expand Up @@ -2060,7 +2085,8 @@ def _augment_response_with_on_demand_transforms(
for odfv_name, _feature_refs in odfv_feature_refs.items():
odfv = requested_odfv_map[odfv_name]
transformed_features_df = odfv.get_transformed_features_df(
initial_response_df, full_feature_names,
initial_response_df,
full_feature_names,
)
selected_subset = [
f for f in transformed_features_df.columns if f in _feature_refs
Expand Down Expand Up @@ -2117,9 +2143,7 @@ def _get_feature_views_to_use(
features: Optional[Union[List[str], FeatureService]],
allow_cache=False,
hide_dummy_entity: bool = True,
) -> Tuple[
List[FeatureView], List[RequestFeatureView], List[OnDemandFeatureView],
]:
) -> Tuple[List[FeatureView], List[RequestFeatureView], List[OnDemandFeatureView]]:

fvs = {
fv.name: fv
Expand Down Expand Up @@ -2364,10 +2388,10 @@ def get_validation_reference(
self, name: str, allow_cache: bool = False
) -> ValidationReference:
"""
Retrieves a validation reference.
Retrieves a validation reference.

Raises:
ValidationReferenceNotFoundException: The validation reference could not be found.
Raises:
ValidationReferenceNotFoundException: The validation reference could not be found.
"""
ref = self._registry.get_validation_reference(
name, project=self.project, allow_cache=allow_cache
Expand Down
Loading