Search…
Python feature server

Overview

The feature server is an HTTP endpoint that serves features with JSON I/O. This enables users to write + read features from Feast online stores using any programming language that can make HTTP requests.

CLI

There is a CLI command that starts the server: feast serve. By default, Feast uses port 6566; the port be overridden by a --port flag.

Deploying as a service

One can also deploy a feature server by building a docker image that bundles in the project's feature_store.yaml. See helm chart for example.
A remote feature server on AWS Lambda is available. A remote feature server on GCP Cloud Run is currently being developed.

Example

Initializing a feature server

Here's the local feature server usage example with the local template:
1
$ feast init feature_repo
2
Creating a new Feast repository in /home/tsotne/feast/feature_repo.
3
4
$ cd feature_repo
5
6
$ feast apply
7
Registered entity driver_id
8
Registered feature view driver_hourly_stats
9
Deploying infrastructure for driver_hourly_stats
10
11
$ feast materialize-incremental $(date +%Y-%m-%d)
12
Materializing 1 feature views to 2021-09-09 17:00:00-07:00 into the sqlite online store.
13
14
driver_hourly_stats from 2021-09-09 16:51:08-07:00 to 2021-09-09 17:00:00-07:00:
15
100%|████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 295.24it/s]
16
17
$ feast serve
18
This is an experimental feature. It's intended for early testing and feedback, and could change without warnings in future releases.
19
INFO: Started server process [8889]
20
09/10/2021 10:42:11 AM INFO:Started server process [8889]
21
INFO: Waiting for application startup.
22
09/10/2021 10:42:11 AM INFO:Waiting for application startup.
23
INFO: Application startup complete.
24
09/10/2021 10:42:11 AM INFO:Application startup complete.
25
INFO: Uvicorn running on http://127.0.0.1:6566 (Press CTRL+C to quit)
26
09/10/2021 10:42:11 AM INFO:Uvicorn running on http://127.0.0.1:6566 (Press CTRL+C to quit)
Copied!

Retrieving features from the online store

After the server starts, we can execute cURL commands from another terminal tab:
1
$ curl -X POST \
2
"http://localhost:6566/get-online-features" \
3
-d '{
4
"features": [
5
"driver_hourly_stats:conv_rate",
6
"driver_hourly_stats:acc_rate",
7
"driver_hourly_stats:avg_daily_trips"
8
],
9
"entities": {
10
"driver_id": [1001, 1002, 1003]
11
}
12
}' | jq
13
{
14
"metadata": {
15
"feature_names": [
16
"driver_id",
17
"conv_rate",
18
"avg_daily_trips",
19
"acc_rate"
20
]
21
},
22
"results": [
23
{
24
"values": [
25
1001,
26
0.7037263512611389,
27
308,
28
0.8724706768989563
29
],
30
"statuses": [
31
"PRESENT",
32
"PRESENT",
33
"PRESENT",
34
"PRESENT"
35
],
36
"event_timestamps": [
37
"1970-01-01T00:00:00Z",
38
"2021-12-31T23:00:00Z",
39
"2021-12-31T23:00:00Z",
40
"2021-12-31T23:00:00Z"
41
]
42
},
43
{
44
"values": [
45
1002,
46
0.038169607520103455,
47
332,
48
0.48534533381462097
49
],
50
"statuses": [
51
"PRESENT",
52
"PRESENT",
53
"PRESENT",
54
"PRESENT"
55
],
56
"event_timestamps": [
57
"1970-01-01T00:00:00Z",
58
"2021-12-31T23:00:00Z",
59
"2021-12-31T23:00:00Z",
60
"2021-12-31T23:00:00Z"
61
]
62
},
63
{
64
"values": [
65
1003,
66
0.9665873050689697,
67
779,
68
0.7793770432472229
69
],
70
"statuses": [
71
"PRESENT",
72
"PRESENT",
73
"PRESENT",
74
"PRESENT"
75
],
76
"event_timestamps": [
77
"1970-01-01T00:00:00Z",
78
"2021-12-31T23:00:00Z",
79
"2021-12-31T23:00:00Z",
80
"2021-12-31T23:00:00Z"
81
]
82
}
83
]
84
}
Copied!
It's also possible to specify a feature service name instead of the list of features:
1
curl -X POST \
2
"http://localhost:6566/get-online-features" \
3
-d '{
4
"feature_service": <feature-service-name>,
5
"entities": {
6
"driver_id": [1001, 1002, 1003]
7
}
8
}' | jq
Copied!

Pushing features to the online store

You can push data corresponding to a push source to the online store (note that timestamps need to be strings):
1
curl -X POST "http://localhost:6566/push" -d '{
2
"push_source_name": "driver_hourly_stats_push_source",
3
"df": {
4
"driver_id": [1001],
5
"event_timestamp": ["2022-05-13 10:59:42"],
6
"created": ["2022-05-13 10:59:42"],
7
"conv_rate": [1.0],
8
"acc_rate": [1.0],
9
"avg_daily_trips": [1000]
10
}
11
}' | jq
Copied!
or equivalently from Python:
1
import json
2
import requests
3
import pandas as pd
4
from datetime import datetime
5
6
event_dict = {
7
"driver_id": [1001],
8
"event_timestamp": [str(datetime(2021, 5, 13, 10, 59, 42))],
9
"created": [str(datetime(2021, 5, 13, 10, 59, 42))],
10
"conv_rate": [1.0],
11
"acc_rate": [1.0],
12
"avg_daily_trips": [1000],
13
"string_feature": "test2",
14
}
15
push_data = {
16
"push_source_name":"driver_stats_push_source",
17
"df":event_dict
18
}
19
requests.post(
20
"http://localhost:6566/push",
21
data=json.dumps(push_data))
Copied!