Serve features to a fraud model
For the complete documentation index see: llms.txt
All documentation pages available in markdown.
With the velocity snapshot pushed to Aerospike, you now read it back through the Python SDK and then through the feast serve HTTP feature server.
The record expires ten minutes after its latest write. If more than ten minutes have passed since the push, run python3 push_velocity.py again before continuing.
Read with the Python SDK
Read the velocity features through the fraud_scoring_v1 FeatureService to confirm the service abstraction works correctly.
-
Create
read_velocity.py:read_velocity.py from feast import FeatureStorestore = FeatureStore(repo_path=".")features = store.get_online_features(features=store.get_feature_service("fraud_scoring_v1"),entity_rows=[{"account_id": "acct-1001"}],).to_dict()print(features)store.get_feature_service("fraud_scoring_v1")passes the named service as thefeaturesargument. This is equivalent to listing"txn_velocity_5m:txn_count_5m","txn_velocity_5m:amount_sum_5m", and"txn_velocity_5m:distinct_merchants_5m"explicitly, but keeps the feature list in the registry rather than scattered across scoring scripts. -
Run it:
Terminal window python3 read_velocity.pyExpected result {'account_id': ['acct-1001'], 'txn_count_5m': [7], 'amount_sum_5m': [1243.5], 'distinct_merchants_5m': [3]}Confirm that all three velocity fields match the values you pushed.
-
Confirm the SDK read:
txn_count_5mis7.amount_sum_5mis1243.5.distinct_merchants_5mis3.
Read through the feature server
feast serve starts a local HTTP server that exposes a /get-online-features endpoint. It lets non-Python services read features with a plain HTTP POST instead of importing the Python SDK.
-
In a separate terminal, start the feature server from
fraud-feast-demo:Terminal window feast serveThe server listens on port 6566 by default. Leave it running for the curl step.
-
Request features over HTTP:
Terminal window curl -s -X POST http://localhost:6566/get-online-features \-H "Content-Type: application/json" \-d '{"feature_service": "fraud_scoring_v1","entities": {"account_id": ["acct-1001"]}}'Expected result {"results": [{"values": ["acct-1001"], "statuses": ["PRESENT"], "event_timestamps": ["1970-01-01T00:00:00Z"]},{"values": [1243.5], "statuses": ["PRESENT"], "event_timestamps": ["2026-07-15T23:33:25Z"]},{"values": [7], "statuses": ["PRESENT"], "event_timestamps": ["2026-07-15T23:33:25Z"]},{"values": [3], "statuses": ["PRESENT"], "event_timestamps": ["2026-07-15T23:33:25Z"]}],"metadata": {"feature_names": ["account_id", "amount_sum_5m", "txn_count_5m", "distinct_merchants_5m"]}}The
event_timestampsin your output differ. The three velocity feature values (1243.5,7,3) should match what you pushed.Each entry in
resultscorresponds to one name listed inmetadata.feature_names. The first entry is the entity key (account_id), which carries the epoch timestamp1970-01-01T00:00:00Zbecause entity keys are not time-stamped values. The three velocity features follow, each with the timestamp of the push.statusesreportsPRESENTwhen Feast finds a stored value for that entity, orMISSINGwhen no value is available (including after the Aerospike record expires). -
Confirm the HTTP read:
- Response
feature_namesincludesamount_sum_5m,txn_count_5m, anddistinct_merchants_5m. - All statuses are
PRESENT.
- Response
-
Stop the feature server with
Ctrl+Cwhen finished.
In production, your fraud service calls the same get_online_features API (SDK or REST) at authorization time while a stream job keeps store.push() current on a flush interval.