|
17 | 17 | "1. Create a synthetic customer feature dataset\n", |
18 | 18 | "2. Register a feature set to represent these features in Feast\n", |
19 | 19 | "3. Ingest these features into Feast\n", |
20 | | - "4. Create a feature query to retrieve historical feature data\n", |
21 | | - "5. Create a feature query to retrieve online feature data" |
| 20 | + "4. Create a feature query and retrieve historical feature data\n", |
| 21 | + "5. Create a feature query and retrieve online feature data" |
22 | 22 | ] |
23 | 23 | }, |
24 | 24 | { |
|
34 | 34 | "metadata": {}, |
35 | 35 | "outputs": [], |
36 | 36 | "source": [ |
37 | | - "!rm -rf feast \\\n", |
38 | | - "&& git clone https://github.com/gojek/feast.git \\\n", |
| 37 | + "!git clone https://github.com/gojek/feast.git \\\n", |
39 | 38 | "&& cd feast/sdk/python/ && pip install --upgrade --quiet -e . \\\n", |
40 | 39 | "&& pip install --quiet --upgrade pandas numpy protobuf" |
41 | 40 | ] |
|
122 | 121 | "cell_type": "code", |
123 | 122 | "execution_count": 25, |
124 | 123 | "metadata": {}, |
125 | | - "outputs": [ |
126 | | - { |
127 | | - "name": "stdout", |
128 | | - "output_type": "stream", |
129 | | - "text": [ |
130 | | - " datetime customer_id daily_transactions \\\n", |
131 | | - "0 2019-12-08 00:00:00+00:00 1001 1.418540 \n", |
132 | | - "1 2019-12-08 00:00:00+00:00 1002 4.231620 \n", |
133 | | - "2 2019-12-08 00:00:00+00:00 1003 2.125182 \n", |
134 | | - "3 2019-12-08 00:00:00+00:00 1004 6.328034 \n", |
135 | | - "4 2019-12-08 00:00:00+00:00 1005 0.009291 \n", |
136 | | - "5 2019-12-07 00:00:00+00:00 1001 1.199422 \n", |
137 | | - "6 2019-12-07 00:00:00+00:00 1002 4.296611 \n", |
138 | | - "7 2019-12-07 00:00:00+00:00 1003 8.178577 \n", |
139 | | - "8 2019-12-07 00:00:00+00:00 1004 4.351829 \n", |
140 | | - "9 2019-12-07 00:00:00+00:00 1005 5.066446 \n", |
141 | | - "\n", |
142 | | - " total_transactions \n", |
143 | | - "0 34 \n", |
144 | | - "1 93 \n", |
145 | | - "2 56 \n", |
146 | | - "3 95 \n", |
147 | | - "4 49 \n", |
148 | | - "5 16 \n", |
149 | | - "6 90 \n", |
150 | | - "7 14 \n", |
151 | | - "8 22 \n", |
152 | | - "9 44 \n" |
153 | | - ] |
154 | | - } |
155 | | - ], |
| 124 | + "outputs": [], |
156 | 125 | "source": [ |
157 | 126 | "customer_features = pd.DataFrame(\n", |
158 | 127 | " {\n", |
|
207 | 176 | "cell_type": "code", |
208 | 177 | "execution_count": 26, |
209 | 178 | "metadata": {}, |
210 | | - "outputs": [ |
211 | | - { |
212 | | - "name": "stdout", |
213 | | - "output_type": "stream", |
214 | | - "text": [ |
215 | | - "Feature daily_transactions (ValueType.DOUBLE) added from dataframe.\n", |
216 | | - " Feature total_transactions (ValueType.INT64) added from dataframe.\n", |
217 | | - " \n" |
218 | | - ] |
219 | | - } |
220 | | - ], |
| 179 | + "outputs": [], |
221 | 180 | "source": [ |
222 | 181 | "customer_fs.infer_fields_from_df(customer_features, replace_existing_features=True)" |
223 | 182 | ] |
|
240 | 199 | "cell_type": "code", |
241 | 200 | "execution_count": 16, |
242 | 201 | "metadata": {}, |
243 | | - "outputs": [ |
244 | | - { |
245 | | - "name": "stdout", |
246 | | - "output_type": "stream", |
247 | | - "text": [ |
248 | | - "No change detected or applied: customer_transactions\n" |
249 | | - ] |
250 | | - } |
251 | | - ], |
| 202 | + "outputs": [], |
252 | 203 | "source": [ |
253 | 204 | "client.apply(customer_fs)" |
254 | 205 | ] |
|
264 | 215 | "cell_type": "code", |
265 | 216 | "execution_count": 17, |
266 | 217 | "metadata": {}, |
267 | | - "outputs": [ |
268 | | - { |
269 | | - "name": "stdout", |
270 | | - "output_type": "stream", |
271 | | - "text": [ |
272 | | - "{\n", |
273 | | - " \"name\": \"customer_transactions\",\n", |
274 | | - " \"version\": 3,\n", |
275 | | - " \"entities\": [\n", |
276 | | - " {\n", |
277 | | - " \"name\": \"customer_id\",\n", |
278 | | - " \"valueType\": \"INT64\"\n", |
279 | | - " }\n", |
280 | | - " ],\n", |
281 | | - " \"features\": [\n", |
282 | | - " {\n", |
283 | | - " \"name\": \"daily_transactions\",\n", |
284 | | - " \"valueType\": \"DOUBLE\"\n", |
285 | | - " },\n", |
286 | | - " {\n", |
287 | | - " \"name\": \"total_transactions\",\n", |
288 | | - " \"valueType\": \"INT64\"\n", |
289 | | - " }\n", |
290 | | - " ],\n", |
291 | | - " \"maxAge\": \"86400s\",\n", |
292 | | - " \"source\": {\n", |
293 | | - " \"type\": \"KAFKA\",\n", |
294 | | - " \"kafkaSourceConfig\": {\n", |
295 | | - " \"bootstrapServers\": \"10.202.112.114:9092\",\n", |
296 | | - " \"topic\": \"feast-features\"\n", |
297 | | - " }\n", |
298 | | - " }\n", |
299 | | - "}\n" |
300 | | - ] |
301 | | - } |
302 | | - ], |
| 218 | + "outputs": [], |
303 | 219 | "source": [ |
304 | 220 | "customer_fs = client.get_feature_set(\"customer_transactions\")\n", |
305 | 221 | "print(customer_fs)" |
|
316 | 232 | "cell_type": "code", |
317 | 233 | "execution_count": 27, |
318 | 234 | "metadata": {}, |
319 | | - "outputs": [ |
320 | | - { |
321 | | - "name": "stderr", |
322 | | - "output_type": "stream", |
323 | | - "text": [ |
324 | | - "\r", |
325 | | - " 0%| | 0/155 [00:00<?, ?rows/s]" |
326 | | - ] |
327 | | - }, |
328 | | - { |
329 | | - "name": "stdout", |
330 | | - "output_type": "stream", |
331 | | - "text": [ |
332 | | - "\n", |
333 | | - "(ingest table to kafka) Ingestion started for customer_transactions:3\n" |
334 | | - ] |
335 | | - }, |
336 | | - { |
337 | | - "name": "stderr", |
338 | | - "output_type": "stream", |
339 | | - "text": [ |
340 | | - "100%|██████████| 155/155 [00:00<00:00, 636.84rows/s]\n", |
341 | | - " 0%| | 0/155 [00:00<?, ?rows/s]" |
342 | | - ] |
343 | | - }, |
344 | | - { |
345 | | - "name": "stdout", |
346 | | - "output_type": "stream", |
347 | | - "text": [ |
348 | | - "\n", |
349 | | - "Ingestion statistics:\n", |
350 | | - "Success: 155/155\n" |
351 | | - ] |
352 | | - }, |
353 | | - { |
354 | | - "name": "stderr", |
355 | | - "output_type": "stream", |
356 | | - "text": [ |
357 | | - "\n" |
358 | | - ] |
359 | | - } |
360 | | - ], |
| 235 | + "outputs": [], |
361 | 236 | "source": [ |
362 | 237 | "client.ingest(\"customer_transactions\", customer_features)" |
363 | 238 | ] |
|
382 | 257 | "cell_type": "code", |
383 | 258 | "execution_count": 30, |
384 | 259 | "metadata": {}, |
385 | | - "outputs": [ |
386 | | - { |
387 | | - "name": "stdout", |
388 | | - "output_type": "stream", |
389 | | - "text": [ |
390 | | - " datetime customer_id\n", |
391 | | - "0 2019-11-27 02:02:25.325169+00:00 1001\n", |
392 | | - "1 2019-12-06 00:27:25.325198+00:00 1002\n", |
393 | | - "2 2019-12-06 15:04:25.325205+00:00 1003\n", |
394 | | - "3 2019-12-02 04:57:25.325210+00:00 1004\n", |
395 | | - "4 2019-12-04 11:16:25.325215+00:00 1005\n", |
396 | | - "5 2019-12-08 03:53:25.325220+00:00 1001\n", |
397 | | - "6 2019-12-07 21:49:25.325226+00:00 1002\n", |
398 | | - "7 2019-12-07 16:14:25.325231+00:00 1003\n", |
399 | | - "8 2019-11-29 06:05:25.325236+00:00 1004\n", |
400 | | - "9 2019-11-27 15:01:25.325241+00:00 1005\n" |
401 | | - ] |
402 | | - } |
403 | | - ], |
| 260 | + "outputs": [], |
404 | 261 | "source": [ |
405 | 262 | "event_timestamps = [datetime.utcnow().replace(tzinfo=utc) - timedelta(days=randrange(15), hours=randrange(24), minutes=randrange(60)) for day in range(30)]\n", |
406 | 263 | "\n", |
|
425 | 282 | "cell_type": "code", |
426 | 283 | "execution_count": 32, |
427 | 284 | "metadata": {}, |
428 | | - "outputs": [ |
429 | | - { |
430 | | - "name": "stdout", |
431 | | - "output_type": "stream", |
432 | | - "text": [ |
433 | | - " uuid event_timestamp \\\n", |
434 | | - "0 9dd6adfe-c8fb-472f-9db6-913827f240dd 2019-11-27 02:02:25.325169+00:00 \n", |
435 | | - "1 5a84f26d-cb3c-4767-8d71-b3cb76e060b4 2019-12-08 03:53:25.325220+00:00 \n", |
436 | | - "2 d458db71-ff1b-4520-8d2d-cba03bed3118 2019-12-01 18:50:25.325246+00:00 \n", |
437 | | - "3 cf6fb51b-4396-442a-a5b7-615550755ac7 2019-12-05 14:35:25.325271+00:00 \n", |
438 | | - "4 b92b0eed-f2e2-49e3-8f1b-b1d3c3cf3072 2019-12-03 10:17:25.325295+00:00 \n", |
439 | | - "5 af4f716a-6c89-48ec-81c8-cb5bbd13e610 2019-11-27 21:01:25.325320+00:00 \n", |
440 | | - "6 c50e69f0-32ed-4af2-93f5-89bd202500ec 2019-12-06 00:27:25.325198+00:00 \n", |
441 | | - "7 fde6a2bb-91ce-4c9f-9112-9e579dcbde1e 2019-12-07 21:49:25.325226+00:00 \n", |
442 | | - "8 c281728f-64a4-4808-91f4-c75d2a2b0329 2019-11-29 16:51:25.325251+00:00 \n", |
443 | | - "9 81e9007c-64b2-48db-9c34-1923a3fd088e 2019-12-06 15:36:25.325275+00:00 \n", |
444 | | - "\n", |
445 | | - " customer_id customer_transactions_v3_daily_transactions \\\n", |
446 | | - "0 1001 NaN \n", |
447 | | - "1 1001 1.41854 \n", |
448 | | - "2 1001 NaN \n", |
449 | | - "3 1001 NaN \n", |
450 | | - "4 1001 NaN \n", |
451 | | - "5 1001 NaN \n", |
452 | | - "6 1002 NaN \n", |
453 | | - "7 1002 NaN \n", |
454 | | - "8 1002 NaN \n", |
455 | | - "9 1002 NaN \n", |
456 | | - "\n", |
457 | | - " customer_transactions_v3_total_transactions \n", |
458 | | - "0 NaN \n", |
459 | | - "1 34.0 \n", |
460 | | - "2 NaN \n", |
461 | | - "3 NaN \n", |
462 | | - "4 NaN \n", |
463 | | - "5 NaN \n", |
464 | | - "6 NaN \n", |
465 | | - "7 NaN \n", |
466 | | - "8 NaN \n", |
467 | | - "9 NaN \n" |
468 | | - ] |
469 | | - } |
470 | | - ], |
| 285 | + "outputs": [], |
471 | 286 | "source": [ |
472 | 287 | "job = client.get_batch_features(\n", |
473 | 288 | " feature_ids=[\n", |
|
514 | 329 | "cell_type": "code", |
515 | 330 | "execution_count": 37, |
516 | 331 | "metadata": {}, |
517 | | - "outputs": [ |
518 | | - { |
519 | | - "ename": "ConnectionError", |
520 | | - "evalue": "Connection timed out while attempting to connect to Feast Serving gRPC server 10.202.112.114:6566 ", |
521 | | - "output_type": "error", |
522 | | - "traceback": [ |
523 | | - "\u001b[0;31m\u001b[0m", |
524 | | - "\u001b[0;31mFutureTimeoutError\u001b[0mTraceback (most recent call last)", |
525 | | - "\u001b[0;32m/opt/notebooks/feast/sdk/python/feast/client.py\u001b[0m in \u001b[0;36m_connect_serving\u001b[0;34m(self, skip_if_connected)\u001b[0m\n\u001b[1;32m 199\u001b[0m grpc.channel_ready_future(self.__serving_channel).result(\n\u001b[0;32m--> 200\u001b[0;31m \u001b[0mtimeout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mGRPC_CONNECTION_TIMEOUT_DEFAULT\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 201\u001b[0m )\n", |
526 | | - "\u001b[0;32m/opt/conda/lib/python3.7/site-packages/grpc/_utilities.py\u001b[0m in \u001b[0;36mresult\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m 139\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 140\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_block\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 141\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", |
527 | | - "\u001b[0;32m/opt/conda/lib/python3.7/site-packages/grpc/_utilities.py\u001b[0m in \u001b[0;36m_block\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m 85\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mremaining\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 86\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mgrpc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mFutureTimeoutError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 87\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", |
528 | | - "\u001b[0;31mFutureTimeoutError\u001b[0m: ", |
529 | | - "\nDuring handling of the above exception, another exception occurred:\n", |
530 | | - "\u001b[0;31mConnectionError\u001b[0mTraceback (most recent call last)", |
531 | | - "\u001b[0;32m<ipython-input-37-4cec522606bd>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 8\u001b[0m fields={\n\u001b[1;32m 9\u001b[0m \"customer_id\": Value(\n\u001b[0;32m---> 10\u001b[0;31m int64_val=1001)\n\u001b[0m\u001b[1;32m 11\u001b[0m }\n\u001b[1;32m 12\u001b[0m )\n", |
532 | | - "\u001b[0;32m/opt/notebooks/feast/sdk/python/feast/client.py\u001b[0m in \u001b[0;36mget_online_features\u001b[0;34m(self, feature_ids, entity_rows)\u001b[0m\n\u001b[1;32m 461\u001b[0m \"\"\"\n\u001b[1;32m 462\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 463\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_connect_serving\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 464\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 465\u001b[0m return self._serving_service_stub.GetOnlineFeatures(\n", |
533 | | - "\u001b[0;32m/opt/notebooks/feast/sdk/python/feast/client.py\u001b[0m in \u001b[0;36m_connect_serving\u001b[0;34m(self, skip_if_connected)\u001b[0m\n\u001b[1;32m 202\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mgrpc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mFutureTimeoutError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 203\u001b[0m raise ConnectionError(\n\u001b[0;32m--> 204\u001b[0;31m \u001b[0;34mf\"Connection timed out while attempting to connect to Feast \"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 205\u001b[0m \u001b[0;34mf\"Serving gRPC server {self.serving_url} \"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 206\u001b[0m )\n", |
534 | | - "\u001b[0;31mConnectionError\u001b[0m: Connection timed out while attempting to connect to Feast Serving gRPC server 10.202.112.114:6566 " |
535 | | - ] |
536 | | - } |
537 | | - ], |
| 332 | + "outputs": [], |
538 | 333 | "source": [ |
539 | 334 | "online_features = online_client.get_online_features(\n", |
540 | 335 | " feature_ids=[\n", |
|
0 commit comments