Skip to content

Commit b504182

Browse files
Run make format-python to fix formatting issues
Co-authored-by: franciscojavierarceo <4163062+franciscojavierarceo@users.noreply.github.com>
1 parent 1008130 commit b504182

File tree

3 files changed

+57
-42
lines changed

3 files changed

+57
-42
lines changed

sdk/python/feast/cli/cli.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,9 @@ def endpoint(ctx: click.Context):
243243
help="Don't validate feature views. Use with caution as this skips important checks.",
244244
)
245245
@click.pass_context
246-
def plan_command(ctx: click.Context, skip_source_validation: bool, skip_validation: bool):
246+
def plan_command(
247+
ctx: click.Context, skip_source_validation: bool, skip_validation: bool
248+
):
247249
"""
248250
Create or update a feature store deployment
249251
"""
@@ -269,7 +271,9 @@ def plan_command(ctx: click.Context, skip_source_validation: bool, skip_validati
269271
help="Don't validate feature views. Use with caution as this skips important checks.",
270272
)
271273
@click.pass_context
272-
def apply_total_command(ctx: click.Context, skip_source_validation: bool, skip_validation: bool):
274+
def apply_total_command(
275+
ctx: click.Context, skip_source_validation: bool, skip_validation: bool
276+
):
273277
"""
274278
Create or update a feature store deployment
275279
"""

sdk/python/feast/repo_operations.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,12 @@ def parse_repo(repo_root: Path) -> RepoContents:
220220
return res
221221

222222

223-
def plan(repo_config: RepoConfig, repo_path: Path, skip_source_validation: bool, skip_validation: bool = False):
223+
def plan(
224+
repo_config: RepoConfig,
225+
repo_path: Path,
226+
skip_source_validation: bool,
227+
skip_validation: bool = False,
228+
):
224229
os.chdir(repo_path)
225230
repo = _get_repo_contents(repo_path, repo_config.project, repo_config)
226231
for project in repo.projects:
@@ -352,13 +357,20 @@ def apply_total_with_repo_instance(
352357
) = extract_objects_for_apply_delete(project_name, registry, repo)
353358

354359
if store._should_use_plan():
355-
registry_diff, infra_diff, new_infra = store.plan(repo, skip_validation=skip_validation)
360+
registry_diff, infra_diff, new_infra = store.plan(
361+
repo, skip_validation=skip_validation
362+
)
356363
click.echo(registry_diff.to_string())
357364

358365
store._apply_diffs(registry_diff, infra_diff, new_infra)
359366
click.echo(infra_diff.to_string())
360367
else:
361-
store.apply(all_to_apply, objects_to_delete=all_to_delete, partial=False, skip_validation=skip_validation)
368+
store.apply(
369+
all_to_apply,
370+
objects_to_delete=all_to_delete,
371+
partial=False,
372+
skip_validation=skip_validation,
373+
)
362374
log_infra_changes(views_to_keep, views_to_delete)
363375

364376

@@ -397,7 +409,12 @@ def create_feature_store(
397409
return FeatureStore(repo_path=str(repo), fs_yaml_file=fs_yaml_file)
398410

399411

400-
def apply_total(repo_config: RepoConfig, repo_path: Path, skip_source_validation: bool, skip_validation: bool = False):
412+
def apply_total(
413+
repo_config: RepoConfig,
414+
repo_path: Path,
415+
skip_source_validation: bool,
416+
skip_validation: bool = False,
417+
):
401418
os.chdir(repo_path)
402419
repo = _get_repo_contents(repo_path, repo_config.project, repo_config)
403420
for project in repo.projects:

sdk/python/tests/unit/test_skip_validation.py

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,18 @@
88
99
Users should be encouraged to report issues on GitHub when they need to use this flag.
1010
"""
11-
from datetime import timedelta
12-
from typing import Any, Dict
1311

14-
import pandas as pd
15-
import pytest
12+
from datetime import timedelta
1613

1714
from feast import Entity, FeatureView, Field
18-
from feast.data_source import RequestSource
1915
from feast.feature_store import FeatureStore
2016
from feast.infra.offline_stores.file_source import FileSource
21-
from feast.on_demand_feature_view import on_demand_feature_view
22-
from feast.types import Float32, Int64
17+
from feast.types import Int64
2318

2419

2520
def test_apply_with_skip_validation_default(tmp_path):
2621
"""Test that FeatureStore.apply() works with default skip_validation=False"""
27-
22+
2823
# Create a temporary feature store
2924
fs = FeatureStore(
3025
config=f"""
@@ -36,15 +31,15 @@ def test_apply_with_skip_validation_default(tmp_path):
3631
path: {tmp_path / "online_store.db"}
3732
"""
3833
)
39-
34+
4035
# Create a basic feature view
4136
batch_source = FileSource(
4237
path=str(tmp_path / "data.parquet"),
4338
timestamp_field="event_timestamp",
4439
)
45-
40+
4641
entity = Entity(name="test_entity", join_keys=["entity_id"])
47-
42+
4843
fv = FeatureView(
4944
name="test_fv",
5045
entities=[entity],
@@ -55,21 +50,21 @@ def test_apply_with_skip_validation_default(tmp_path):
5550
source=batch_source,
5651
ttl=timedelta(days=1),
5752
)
58-
53+
5954
# Apply with default skip_validation (should be False)
6055
fs.apply([entity, fv])
61-
56+
6257
# Verify the feature view was applied
6358
feature_views = fs.list_feature_views()
6459
assert len(feature_views) == 1
6560
assert feature_views[0].name == "test_fv"
66-
61+
6762
fs.teardown()
6863

6964

7065
def test_apply_with_skip_validation_true(tmp_path):
7166
"""Test that FeatureStore.apply() accepts skip_validation=True parameter"""
72-
67+
7368
# Create a temporary feature store
7469
fs = FeatureStore(
7570
config=f"""
@@ -81,15 +76,15 @@ def test_apply_with_skip_validation_true(tmp_path):
8176
path: {tmp_path / "online_store.db"}
8277
"""
8378
)
84-
79+
8580
# Create a basic feature view
8681
batch_source = FileSource(
8782
path=str(tmp_path / "data.parquet"),
8883
timestamp_field="event_timestamp",
8984
)
90-
85+
9186
entity = Entity(name="test_entity", join_keys=["entity_id"])
92-
87+
9388
fv = FeatureView(
9489
name="test_fv",
9590
entities=[entity],
@@ -100,23 +95,23 @@ def test_apply_with_skip_validation_true(tmp_path):
10095
source=batch_source,
10196
ttl=timedelta(days=1),
10297
)
103-
98+
10499
# Apply with skip_validation=True
105100
# This should skip the _validate_all_feature_views() call
106101
fs.apply([entity, fv], skip_validation=True)
107-
102+
108103
# Verify the feature view was applied
109104
feature_views = fs.list_feature_views()
110105
assert len(feature_views) == 1
111106
assert feature_views[0].name == "test_fv"
112-
107+
113108
fs.teardown()
114109

115110

116111
def test_plan_with_skip_validation_parameter(tmp_path):
117112
"""Test that FeatureStore.plan() accepts skip_validation parameter"""
118113
from feast.feature_store import RepoContents
119-
114+
120115
# Create a temporary feature store
121116
fs = FeatureStore(
122117
config=f"""
@@ -128,15 +123,15 @@ def test_plan_with_skip_validation_parameter(tmp_path):
128123
path: {tmp_path / "online_store.db"}
129124
"""
130125
)
131-
126+
132127
# Create a basic feature view
133128
batch_source = FileSource(
134129
path=str(tmp_path / "data.parquet"),
135130
timestamp_field="event_timestamp",
136131
)
137-
132+
138133
entity = Entity(name="test_entity", join_keys=["entity_id"])
139-
134+
140135
fv = FeatureView(
141136
name="test_fv",
142137
entities=[entity],
@@ -147,7 +142,7 @@ def test_plan_with_skip_validation_parameter(tmp_path):
147142
source=batch_source,
148143
ttl=timedelta(days=1),
149144
)
150-
145+
151146
# Create repo contents
152147
repo_contents = RepoContents(
153148
feature_views=[fv],
@@ -158,41 +153,40 @@ def test_plan_with_skip_validation_parameter(tmp_path):
158153
feature_services=[],
159154
permissions=[],
160155
)
161-
156+
162157
# Plan with skip_validation=False (default)
163158
registry_diff, infra_diff, new_infra = fs.plan(repo_contents, skip_validation=False)
164-
159+
165160
# Verify the diff shows the feature view will be added
166161
assert len(registry_diff.fv_to_add) == 1
167-
162+
168163
# Plan with skip_validation=True
169164
registry_diff, infra_diff, new_infra = fs.plan(repo_contents, skip_validation=True)
170-
165+
171166
# Verify the diff still works correctly
172167
assert len(registry_diff.fv_to_add) == 1
173-
168+
174169
fs.teardown()
175170

176171

177172
def test_skip_validation_use_case_documentation():
178173
"""
179174
Documentation test: This test documents the key use case for skip_validation.
180-
175+
181176
The skip_validation flag is particularly important for On-Demand Feature Views (ODFVs)
182177
that use feature transformations. During the apply() process, ODFVs call infer_features()
183178
which internally uses _construct_random_input() to validate the transformation.
184-
179+
185180
Sometimes this validation can be overly strict or fail for complex transformations.
186181
In such cases, users can use skip_validation=True to bypass this check.
187-
182+
188183
Example use case from the issue:
189184
- User has an ODFV with a complex transformation
190185
- The _construct_random_input validation fails or is too restrictive
191186
- User can now call: fs.apply([odfv], skip_validation=True)
192187
- The ODFV is registered without going through the validation
193-
188+
194189
Note: Users should be encouraged to report such cases on GitHub so the Feast team
195190
can improve the validation system.
196191
"""
197192
pass # This is a documentation test
198-

0 commit comments

Comments
 (0)