Skip to content

Commit 784501f

Browse files
updated tests
Signed-off-by: Francisco Javier Arceo <farceo@redhat.com>
1 parent 30ac5ad commit 784501f

4 files changed

Lines changed: 286 additions & 150 deletions

File tree

docs/reference/feature-servers/python-feature-server.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,52 @@ requests.post(
200200
data=json.dumps(push_data))
201201
```
202202

203+
### Materializing features
204+
205+
The Python feature server also exposes an endpoint for materializing features from the offline store to the online store.
206+
207+
**Standard materialization with timestamps:**
208+
```bash
209+
curl -X POST "http://localhost:6566/materialize" -d '{
210+
"start_ts": "2021-01-01T00:00:00",
211+
"end_ts": "2021-01-02T00:00:00",
212+
"feature_views": ["driver_hourly_stats"]
213+
}' | jq
214+
```
215+
216+
**Materialize all data without event timestamps:**
217+
```bash
218+
curl -X POST "http://localhost:6566/materialize" -d '{
219+
"feature_views": ["driver_hourly_stats"],
220+
"disable_event_timestamp": true
221+
}' | jq
222+
```
223+
224+
When `disable_event_timestamp` is set to `true`, the `start_ts` and `end_ts` parameters are not required, and all available data is materialized using the current datetime as the event timestamp. This is useful when your source data lacks proper event timestamp columns.
225+
226+
Or from Python:
227+
```python
228+
import json
229+
import requests
230+
231+
# Standard materialization
232+
materialize_data = {
233+
"start_ts": "2021-01-01T00:00:00",
234+
"end_ts": "2021-01-02T00:00:00",
235+
"feature_views": ["driver_hourly_stats"]
236+
}
237+
238+
# Materialize without event timestamps
239+
materialize_data_no_timestamps = {
240+
"feature_views": ["driver_hourly_stats"],
241+
"disable_event_timestamp": True
242+
}
243+
244+
requests.post(
245+
"http://localhost:6566/materialize",
246+
data=json.dumps(materialize_data))
247+
```
248+
203249
## Starting the feature server in TLS(SSL) mode
204250

205251
Enabling TLS mode ensures that data between the Feast client and server is transmitted securely. For an ideal production environment, it is recommended to start the feature server in TLS mode.

sdk/python/feast/feature_server.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ class PushFeaturesRequest(BaseModel):
7474

7575

7676
class MaterializeRequest(BaseModel):
77-
start_ts: str
78-
end_ts: str
77+
start_ts: Optional[str] = None
78+
end_ts: Optional[str] = None
7979
feature_views: Optional[List[str]] = None
8080
disable_event_timestamp: bool = False
8181

@@ -441,6 +441,8 @@ def materialize(request: MaterializeRequest) -> None:
441441
start_date = datetime(1970, 1, 1) # Beginning of time to capture all historical data
442442
end_date = now
443443
else:
444+
if not request.start_ts or not request.end_ts:
445+
raise ValueError("start_ts and end_ts are required when disable_event_timestamp is False")
444446
start_date = utils.make_tzaware(parser.parse(request.start_ts))
445447
end_date = utils.make_tzaware(parser.parse(request.end_ts))
446448

sdk/python/tests/unit/cli/test_cli.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,31 @@ def test_cli_configuration():
190190
assertpy.assert_that(output).contains(b"path: data/online_store.db")
191191
assertpy.assert_that(output).contains(b"type: file")
192192
assertpy.assert_that(output).contains(b"entity_key_serialization_version: 3")
193+
194+
195+
def test_cli_materialize_disable_event_timestamp():
196+
"""
197+
Unit test for the 'feast materialize --disable-event-timestamp' command
198+
"""
199+
runner = CliRunner()
200+
201+
with setup_third_party_provider_repo("local") as repo_path:
202+
# Test that --disable-event-timestamp flag works without timestamps
203+
return_code, output = runner.run_with_output(
204+
["materialize", "--disable-event-timestamp"], cwd=repo_path
205+
)
206+
# Should succeed (though may not have data to materialize)
207+
assertpy.assert_that(return_code).is_equal_to(0)
208+
209+
# Test that providing timestamps with --disable-event-timestamp fails
210+
return_code, output = runner.run_with_output(
211+
["materialize", "--disable-event-timestamp", "2021-01-01T00:00:00", "2021-01-02T00:00:00"],
212+
cwd=repo_path
213+
)
214+
assertpy.assert_that(return_code).is_equal_to(2) # Click usage error
215+
assertpy.assert_that(output).contains(b"Cannot specify START_TS or END_TS when --disable-event-timestamp is used")
216+
217+
# Test that missing timestamps without flag fails
218+
return_code, output = runner.run_with_output(["materialize"], cwd=repo_path)
219+
assertpy.assert_that(return_code).is_equal_to(2) # Click usage error
220+
assertpy.assert_that(output).contains(b"START_TS and END_TS are required unless --disable-event-timestamp is used")

0 commit comments

Comments
 (0)