{
"cells": [
{
"cell_type": "markdown",
"id": "0e8be874",
"metadata": {},
"source": [
"### Deploy and Serve a Feature List for Model Predictions\n",
"\n",
"Once you have a feature list ready, it's essential to serve these features effectively to make real-time or batch predictions using your machine learning model.\n",
"\n",
"In this section, we'll take the feature list we previously crafted and explore two primary ways to serve its values:\n",
"\n",
"**REST API:** Ideal for real-time predictions where you need instantaneous results. For instance, in applications where user interactions require immediate feedback based on model predictions.\n",
"\n",
"**Batch Processing:** Best suited for scenarios where you have a bulk of data and don't require instant results."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "e6475ae1",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[32;20m16:46:03\u001b[0m | \u001b[1m\u001b[38;20mINFO \u001b[0m\u001b[0m | \u001b[1m\u001b[38;20mUsing configuration file at: /Users/viktor/.featurebyte/config.yaml\u001b[0m\u001b[0m\n",
"\u001b[32;20m16:46:03\u001b[0m | \u001b[1m\u001b[38;20mINFO \u001b[0m\u001b[0m | \u001b[1m\u001b[38;20mActive profile: tutorial (https://tutorials.featurebyte.com/api/v1)\u001b[0m\u001b[0m\n",
"\u001b[32;20m16:46:04\u001b[0m | \u001b[1m\u001b[38;20mINFO \u001b[0m\u001b[0m | \u001b[1m\u001b[38;20mSDK version: 0.6.0.dev121\u001b[0m\u001b[0m\n",
"\u001b[32;20m16:46:04\u001b[0m | \u001b[1m\u001b[38;20mINFO \u001b[0m\u001b[0m | \u001b[1m\u001b[38;20mNo catalog activated.\u001b[0m\u001b[0m\n",
"\u001b[32;20m16:46:04\u001b[0m | \u001b[1m\u001b[38;20mINFO \u001b[0m\u001b[0m | \u001b[1m\u001b[38;20m10 feature lists, 59 features deployed\u001b[0m\u001b[0m\n",
"\u001b[32;20m16:46:04\u001b[0m | \u001b[1m\u001b[38;20mINFO \u001b[0m\u001b[0m | \u001b[1m\u001b[38;20mUsing profile: tutorial\u001b[0m\u001b[0m\n",
"\u001b[32;20m16:46:04\u001b[0m | \u001b[1m\u001b[38;20mINFO \u001b[0m\u001b[0m | \u001b[1m\u001b[38;20mUsing configuration file at: /Users/viktor/.featurebyte/config.yaml\u001b[0m\u001b[0m\n",
"\u001b[32;20m16:46:04\u001b[0m | \u001b[1m\u001b[38;20mINFO \u001b[0m\u001b[0m | \u001b[1m\u001b[38;20mActive profile: tutorial (https://tutorials.featurebyte.com/api/v1)\u001b[0m\u001b[0m\n",
"\u001b[32;20m16:46:04\u001b[0m | \u001b[1m\u001b[38;20mINFO \u001b[0m\u001b[0m | \u001b[1m\u001b[38;20mSDK version: 0.6.0.dev121\u001b[0m\u001b[0m\n",
"\u001b[32;20m16:46:04\u001b[0m | \u001b[1m\u001b[38;20mINFO \u001b[0m\u001b[0m | \u001b[1m\u001b[38;20mNo catalog activated.\u001b[0m\u001b[0m\n",
"\u001b[32;20m16:46:05\u001b[0m | \u001b[1m\u001b[38;20mINFO \u001b[0m\u001b[0m | \u001b[1m\u001b[38;20m10 feature lists, 59 features deployed\u001b[0m\u001b[0m\n",
"\u001b[32;20m16:46:05\u001b[0m | \u001b[1m\u001b[38;20mINFO \u001b[0m\u001b[0m | \u001b[1m\u001b[38;20mCatalog activated: Grocery Dataset Tutorial\u001b[0m\u001b[0m\n"
]
}
],
"source": [
"import featurebyte as fb\n",
"from datetime import datetime\n",
"\n",
"# Set your profile to the tutorial environment\n",
"fb.use_profile(\"tutorial\")\n",
"\n",
"catalog_name = \"Grocery Dataset Tutorial\"\n",
"catalog = fb.Catalog.activate(catalog_name) "
]
},
{
"cell_type": "markdown",
"id": "cb3085ea",
"metadata": {},
"source": [
"#### List feature lists in Catalog"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "25d0339a",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" id | \n",
" name | \n",
" num_feature | \n",
" status | \n",
" deployed | \n",
" readiness_frac | \n",
" online_frac | \n",
" tables | \n",
" entities | \n",
" primary_entity | \n",
" created_at | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 6564b959d3f7244b7fc926a0 | \n",
" Customer Simple FeatureList | \n",
" 7 | \n",
" DRAFT | \n",
" False | \n",
" 0.0 | \n",
" 0.0 | \n",
" [GROCERYCUSTOMER, GROCERYINVOICE, INVOICEITEMS... | \n",
" [customer] | \n",
" [customer] | \n",
" 2023-11-27T15:44:36.966000 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" id name num_feature status \\\n",
"0 6564b959d3f7244b7fc926a0 Customer Simple FeatureList 7 DRAFT \n",
"\n",
" deployed readiness_frac online_frac \\\n",
"0 False 0.0 0.0 \n",
"\n",
" tables entities \\\n",
"0 [GROCERYCUSTOMER, GROCERYINVOICE, INVOICEITEMS... [customer] \n",
"\n",
" primary_entity created_at \n",
"0 [customer] 2023-11-27T15:44:36.966000 "
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"catalog.list_feature_lists()"
]
},
{
"cell_type": "markdown",
"id": "abe93856",
"metadata": {},
"source": [
"#### Get a feature list from Catalog"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "96147a09",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Loading Feature(s) |████████████████████████████████████████| 7/7 [100%] in 0.7s\n"
]
}
],
"source": [
"simple_feature_list = catalog.get_feature_list(\"Customer Simple FeatureList\")"
]
},
{
"cell_type": "markdown",
"id": "d9d8f22f",
"metadata": {},
"source": [
"#### Deploy feature list"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "7c0fbd38",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done! |████████████████████████████████████████| 100% in 6.5s (0.16%/s) \n",
"Done! |████████████████████████████████████████| 100% in 3.3s (0.31%/s) \n"
]
}
],
"source": [
"# Create a deployment\n",
"deployment = simple_feature_list.deploy(\n",
" deployment_name=\"Customer Spending forecast\",\n",
" make_production_ready=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "51119653",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done! |████████████████████████████████████████| 100% in 42.0s (0.02%/s) \n"
]
}
],
"source": [
"# Enable deployment\n",
"deployment.enable()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "9e6603e5",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" id | \n",
" name | \n",
" feature_list_name | \n",
" feature_list_version | \n",
" num_feature | \n",
" enabled | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 6564b9c77927bf2a9d6cca65 | \n",
" Customer Spending forecast | \n",
" Customer Simple FeatureList | \n",
" V231127 | \n",
" 7 | \n",
" True | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" id name \\\n",
"0 6564b9c77927bf2a9d6cca65 Customer Spending forecast \n",
"\n",
" feature_list_name feature_list_version num_feature enabled \n",
"0 Customer Simple FeatureList V231127 7 True "
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Check that the deployment is enabled\n",
"catalog.list_deployments()"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "35919198",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"simple_feature_list.status: DEPLOYED\n"
]
}
],
"source": [
"# Check status of the feature list\n",
"print(\"simple_feature_list.status:\", simple_feature_list.status)"
]
},
{
"cell_type": "markdown",
"id": "57ae146d",
"metadata": {},
"source": [
"#### Get template for online serving"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "1428f1bb",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
"from typing import Any, Dict\n",
"\n",
"import pandas as pd\n",
"import requests\n",
"\n",
"\n",
"def request_features(entity_serving_names: Dict[str, Any]) -> pd.DataFrame:\n",
" """\n",
" Send POST request to online serving endpoint\n",
"\n",
" Parameters\n",
" ----------\n",
" entity_serving_names: Dict[str, Any]\n",
" Entity serving name values to used for serving request\n",
"\n",
" Returns\n",
" -------\n",
" pd.DataFrame\n",
" """\n",
" response = requests.post(\n",
" url="https://tutorials.featurebyte.com/api/v1/deployment/6564b9c77927bf2a9d6cca65/online_features",\n",
" headers={"Content-Type": "application/json", "active-catalog-id": "6564b7da5cf4e2dd964abb60", "Authorization": "Bearer 2u5EXHbdmiHNjEC4Y-EXBBJV-yeBiS35I4kK7FMjsLI"},\n",
" json={"entity_serving_names": entity_serving_names},\n",
" )\n",
" assert response.status_code == 200, response.json()\n",
" return pd.DataFrame.from_dict(response.json()["features"])\n",
"\n",
"\n",
"request_features([{"GROCERYCUSTOMERGUID": "016d7230-8602-42ef-9861-c672f48fb010"}])\n",
"
\n",
"
"
],
"text/plain": [
"'from typing import Any, Dict\\n\\nimport pandas as pd\\nimport requests\\n\\n\\ndef request_features(entity_serving_names: Dict[str, Any]) -> pd.DataFrame:\\n \"\"\"\\n Send POST request to online serving endpoint\\n\\n Parameters\\n ----------\\n entity_serving_names: Dict[str, Any]\\n Entity serving name values to used for serving request\\n\\n Returns\\n -------\\n pd.DataFrame\\n \"\"\"\\n response = requests.post(\\n url=\"https://tutorials.featurebyte.com/api/v1/deployment/6564b9c77927bf2a9d6cca65/online_features\",\\n headers={\"Content-Type\": \"application/json\", \"active-catalog-id\": \"6564b7da5cf4e2dd964abb60\", \"Authorization\": \"Bearer 2u5EXHbdmiHNjEC4Y-EXBBJV-yeBiS35I4kK7FMjsLI\"},\\n json={\"entity_serving_names\": entity_serving_names},\\n )\\n assert response.status_code == 200, response.json()\\n return pd.DataFrame.from_dict(response.json()[\"features\"])\\n\\n\\nrequest_features([{\"GROCERYCUSTOMERGUID\": \"016d7230-8602-42ef-9861-c672f48fb010\"}])'"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Get a python template for consuming the feature serving API\n",
"deployment.get_online_serving_code(language=\"python\")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "f448dd57",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
"#!/bin/sh\n",
"\n",
"curl -X POST \\\n",
" -H 'Content-Type: application/json' \\\n",
" -H 'active-catalog-id: 6564b7da5cf4e2dd964abb60' \\\n",
" -H 'Authorization: Bearer 2u5EXHbdmiHNjEC4Y-EXBBJV-yeBiS35I4kK7FMjsLI' \\\n",
" -d '{"entity_serving_names": [{"GROCERYCUSTOMERGUID": "016d7230-8602-42ef-9861-c672f48fb010"}]}' \\\n",
" https://tutorials.featurebyte.com/api/v1/deployment/6564b9c77927bf2a9d6cca65/online_features\n",
"
\n",
"
"
],
"text/plain": [
"'#!/bin/sh\\n\\ncurl -X POST \\\\\\n -H \\'Content-Type: application/json\\' \\\\\\n -H \\'active-catalog-id: 6564b7da5cf4e2dd964abb60\\' \\\\\\n -H \\'Authorization: Bearer 2u5EXHbdmiHNjEC4Y-EXBBJV-yeBiS35I4kK7FMjsLI\\' \\\\\\n -d \\'{\"entity_serving_names\": [{\"GROCERYCUSTOMERGUID\": \"016d7230-8602-42ef-9861-c672f48fb010\"}]}\\' \\\\\\n https://tutorials.featurebyte.com/api/v1/deployment/6564b9c77927bf2a9d6cca65/online_features'"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Get shell script\n",
"deployment.get_online_serving_code(language=\"sh\")"
]
},
{
"cell_type": "markdown",
"id": "282901eb",
"metadata": {},
"source": [
"#### Create batch request table"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "50d8cfd1",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# Get view of current customer\n",
"customer_table = catalog.get_table(\"GROCERYCUSTOMER\")\n",
"customer_view = customer_table.get_view(view_mode=\"manual\")\n",
"cond = customer_view.CurrentRecord == True\n",
"current_customer_view = customer_view[cond]"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "0c1cde26",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"[\n",
" {\n",
" 'name': 'customer',\n",
" 'created_at': '2023-11-27T15:39:09.477000',\n",
" 'updated_at': '2023-11-27T15:39:19.968000',\n",
" 'description': None,\n",
" 'serving_names': [\n",
" 'GROCERYCUSTOMERGUID'\n",
" ],\n",
" 'catalog_name': 'Grocery Dataset Tutorial'\n",
" }]"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Check primary entity of the deployed feature list to obtain its serving name\n",
"simple_feature_list.primary_entity"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "1194a65d",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done! |████████████████████████████████████████| 100% in 6.5s (0.16%/s) \n"
]
}
],
"source": [
"# Create batch request table from the view\n",
"batch_request_table = current_customer_view.create_batch_request_table(\n",
" name=\"Current Customers at \" + datetime.now().strftime(\"%Y%m%d:%H%M\"),\n",
" columns=[\"GroceryCustomerGuid\"],\n",
" columns_rename_mapping={\n",
" \"GroceryCustomerGuid\": \"GROCERYCUSTOMERGUID\",\n",
" }\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "02951faf",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"'Current Customers at 20231127:1647'"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Get name of the batch request table\n",
"batch_request_table.name"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "11a53ab8",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" id | \n",
" name | \n",
" type | \n",
" shape | \n",
" feature_store_name | \n",
" created_at | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 6564b9fa7927bf2a9d6cca66 | \n",
" Current Customers at 20231127:1647 | \n",
" view | \n",
" [500, 1] | \n",
" playground | \n",
" 2023-11-27T15:47:08.828000 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" id name type \\\n",
"0 6564b9fa7927bf2a9d6cca66 Current Customers at 20231127:1647 view \n",
"\n",
" shape feature_store_name created_at \n",
"0 [500, 1] playground 2023-11-27T15:47:08.828000 "
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# List batch request tables in catalog\n",
"catalog.list_batch_request_tables()"
]
},
{
"cell_type": "markdown",
"id": "eb6ef8ec",
"metadata": {},
"source": [
"#### Compute batch feature table"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "2c47638e",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# Get deployment and batch request table\n",
"deployment = catalog.get_deployment(\"Customer Spending forecast\")\n",
"batch_request_table = catalog.get_batch_request_table(batch_request_table.name)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "b9494894",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done! |████████████████████████████████████████| 100% in 9.8s (0.10%/s) \n"
]
}
],
"source": [
"# Compute batch features\n",
"batch_features = deployment.compute_batch_feature_table(\n",
" batch_request_table=batch_request_table,\n",
" batch_feature_table_name = \n",
" f\"Customer Simple FeatureList for Spending forecast with {batch_request_table.name}\"\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "02737afa",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" id | \n",
" name | \n",
" feature_store_name | \n",
" batch_request_table_name | \n",
" shape | \n",
" created_at | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 6564ba027927bf2a9d6cca67 | \n",
" Customer Simple FeatureList for Spending forec... | \n",
" playground | \n",
" Current Customers at 20231127:1647 | \n",
" [500, 8] | \n",
" 2023-11-27T15:47:19.526000 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" id \\\n",
"0 6564ba027927bf2a9d6cca67 \n",
"\n",
" name feature_store_name \\\n",
"0 Customer Simple FeatureList for Spending forec... playground \n",
"\n",
" batch_request_table_name shape created_at \n",
"0 Current Customers at 20231127:1647 [500, 8] 2023-11-27T15:47:19.526000 "
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# List observation tables\n",
"catalog.list_batch_feature_tables()"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "df35fc25",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Downloading table |████████████████████████████████████████| 500/500 [100%] in 0\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" GROCERYCUSTOMERGUID | \n",
" CUSTOMER_Age_band | \n",
" CUSTOMER_Latest_invoice_Amount | \n",
" CUSTOMER_Count_of_invoice_14d | \n",
" CUSTOMER_Avg_of_invoice_Amount_14d | \n",
" CUSTOMER_Std_of_invoice_Amount_14d | \n",
" CUSTOMER_Latest_invoice_Amount_Z_Score_to_invoice_Amount_28d | \n",
" CUSTOMER_vs_OVERALL_item_TotalCost_across_product_ProductGroups_26w | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" c4f35072-c0ae-48b4-9f61-4bd4c348e48a | \n",
" 60-64 | \n",
" 10.09 | \n",
" 0.0 | \n",
" NaN | \n",
" NaN | \n",
" NaN | \n",
" 0.740359 | \n",
"
\n",
" \n",
" 1 | \n",
" c003c0a7-73f3-41c8-be4e-a7b0ede84312 | \n",
" 30-34 | \n",
" 17.98 | \n",
" 0.0 | \n",
" NaN | \n",
" NaN | \n",
" NaN | \n",
" 0.348179 | \n",
"
\n",
" \n",
" 2 | \n",
" 1d15db25-a662-41d5-9bad-1079b1e443ed | \n",
" 40-44 | \n",
" 6.00 | \n",
" 0.0 | \n",
" NaN | \n",
" NaN | \n",
" -1.000000 | \n",
" 0.663154 | \n",
"
\n",
" \n",
" 3 | \n",
" 6a780e8d-0c03-4246-b08c-d76be43470bb | \n",
" 35-39 | \n",
" 8.98 | \n",
" 7.0 | \n",
" 7.734286 | \n",
" 7.824217 | \n",
" -0.026837 | \n",
" 0.774803 | \n",
"
\n",
" \n",
" 4 | \n",
" 716c079e-a98f-456c-af24-ed7b1d87b38d | \n",
" 85-89 | \n",
" 5.76 | \n",
" 0.0 | \n",
" NaN | \n",
" NaN | \n",
" 1.000000 | \n",
" 0.733773 | \n",
"
\n",
" \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
" ... | \n",
"
\n",
" \n",
" 495 | \n",
" 1c35daf7-e880-403f-95ab-3a2f3295f303 | \n",
" 60-64 | \n",
" 10.12 | \n",
" 2.0 | \n",
" 6.535000 | \n",
" 3.585000 | \n",
" 0.464564 | \n",
" 0.738185 | \n",
"
\n",
" \n",
" 496 | \n",
" d90fda3d-2dfb-4be0-bbcf-2b5c46c97e19 | \n",
" 60-64 | \n",
" 2.68 | \n",
" 3.0 | \n",
" 12.060000 | \n",
" 11.073328 | \n",
" -1.246973 | \n",
" 0.641640 | \n",
"
\n",
" \n",
" 497 | \n",
" f4c7dce9-ea7d-4af2-98c6-3630b7cd869d | \n",
" 70-74 | \n",
" 32.73 | \n",
" 1.0 | \n",
" 32.730000 | \n",
" 0.000000 | \n",
" 1.221433 | \n",
" 0.780169 | \n",
"
\n",
" \n",
" 498 | \n",
" 62fd4b3d-a46c-4166-971e-3c2041d7d4d8 | \n",
" 20-24 | \n",
" 3.88 | \n",
" 2.0 | \n",
" 4.440000 | \n",
" 0.560000 | \n",
" 0.315371 | \n",
" 0.451703 | \n",
"
\n",
" \n",
" 499 | \n",
" f8d62c21-4337-4a68-9063-ad3f8d16aa21 | \n",
" 85-89 | \n",
" 19.52 | \n",
" 0.0 | \n",
" NaN | \n",
" NaN | \n",
" -1.034224 | \n",
" 0.628090 | \n",
"
\n",
" \n",
"
\n",
"
500 rows × 8 columns
\n",
"
"
],
"text/plain": [
" GROCERYCUSTOMERGUID CUSTOMER_Age_band \\\n",
"0 c4f35072-c0ae-48b4-9f61-4bd4c348e48a 60-64 \n",
"1 c003c0a7-73f3-41c8-be4e-a7b0ede84312 30-34 \n",
"2 1d15db25-a662-41d5-9bad-1079b1e443ed 40-44 \n",
"3 6a780e8d-0c03-4246-b08c-d76be43470bb 35-39 \n",
"4 716c079e-a98f-456c-af24-ed7b1d87b38d 85-89 \n",
".. ... ... \n",
"495 1c35daf7-e880-403f-95ab-3a2f3295f303 60-64 \n",
"496 d90fda3d-2dfb-4be0-bbcf-2b5c46c97e19 60-64 \n",
"497 f4c7dce9-ea7d-4af2-98c6-3630b7cd869d 70-74 \n",
"498 62fd4b3d-a46c-4166-971e-3c2041d7d4d8 20-24 \n",
"499 f8d62c21-4337-4a68-9063-ad3f8d16aa21 85-89 \n",
"\n",
" CUSTOMER_Latest_invoice_Amount CUSTOMER_Count_of_invoice_14d \\\n",
"0 10.09 0.0 \n",
"1 17.98 0.0 \n",
"2 6.00 0.0 \n",
"3 8.98 7.0 \n",
"4 5.76 0.0 \n",
".. ... ... \n",
"495 10.12 2.0 \n",
"496 2.68 3.0 \n",
"497 32.73 1.0 \n",
"498 3.88 2.0 \n",
"499 19.52 0.0 \n",
"\n",
" CUSTOMER_Avg_of_invoice_Amount_14d CUSTOMER_Std_of_invoice_Amount_14d \\\n",
"0 NaN NaN \n",
"1 NaN NaN \n",
"2 NaN NaN \n",
"3 7.734286 7.824217 \n",
"4 NaN NaN \n",
".. ... ... \n",
"495 6.535000 3.585000 \n",
"496 12.060000 11.073328 \n",
"497 32.730000 0.000000 \n",
"498 4.440000 0.560000 \n",
"499 NaN NaN \n",
"\n",
" CUSTOMER_Latest_invoice_Amount_Z_Score_to_invoice_Amount_28d \\\n",
"0 NaN \n",
"1 NaN \n",
"2 -1.000000 \n",
"3 -0.026837 \n",
"4 1.000000 \n",
".. ... \n",
"495 0.464564 \n",
"496 -1.246973 \n",
"497 1.221433 \n",
"498 0.315371 \n",
"499 -1.034224 \n",
"\n",
" CUSTOMER_vs_OVERALL_item_TotalCost_across_product_ProductGroups_26w \n",
"0 0.740359 \n",
"1 0.348179 \n",
"2 0.663154 \n",
"3 0.774803 \n",
"4 0.733773 \n",
".. ... \n",
"495 0.738185 \n",
"496 0.641640 \n",
"497 0.780169 \n",
"498 0.451703 \n",
"499 0.628090 \n",
"\n",
"[500 rows x 8 columns]"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Convert to pandas \n",
"batch_features.to_pandas()"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "a769a10b",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Downloading table |████████████████████████████████████████| 500/500 [100%] in 0\n"
]
},
{
"data": {
"text/plain": [
"PosixPath('BATCH_FEATURE_TABLE_6564ba03083bd15e6cb1e755.parquet')"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# download parquet file\n",
"batch_features.download()"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "b55ad8d2",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done! |████████████████████████████████████████| 100% in 6.5s (0.16%/s) \n",
"Done! |████████████████████████████████████████| 100% in 6.5s (0.16%/s) \n"
]
}
],
"source": [
"# delete if not needed any more\n",
"batch_features.delete()\n",
"batch_request_table.delete()"
]
},
{
"cell_type": "markdown",
"id": "3d0b71de",
"metadata": {},
"source": [
"#### Manage Deployment"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "d94c0462",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"deployment = catalog.get_deployment(\"Customer Spending forecast\")"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "d7e4affb",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Loading Feature(s) |████████████████████████████████████████| 7/7 [100%] in 0.7s\n"
]
},
{
"data": {
"text/html": [
"\n",
"
Job statistics (last 1 hours)
\n",
"
\n",
" \n",
" \n",
" | \n",
" request_date | \n",
" job_history_window | \n",
" job_duration_tolerance | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 2023-11-27T15:47:48.386771 | \n",
" 1 | \n",
" 60 | \n",
"
\n",
" \n",
"
\n",
"
\n",
" \n",
" \n",
" | \n",
" feature_name | \n",
" aggregation_hash | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" CUSTOMER_Avg_of_invoice_Amount_14d | \n",
" 45351576 | \n",
"
\n",
" \n",
" 1 | \n",
" CUSTOMER_Count_of_invoice_14d | \n",
" 7cee376c | \n",
"
\n",
" \n",
" 2 | \n",
" CUSTOMER_Latest_invoice_Amount | \n",
" 0ee300b2 | \n",
"
\n",
" \n",
" 3 | \n",
" CUSTOMER_Latest_invoice_Amount_Z_Score_to_invoice_Amount_28d | \n",
" 0ee300b2 | \n",
"
\n",
" \n",
" 4 | \n",
" CUSTOMER_Latest_invoice_Amount_Z_Score_to_invoice_Amount_28d | \n",
" 45351576 | \n",
"
\n",
" \n",
" 5 | \n",
" CUSTOMER_Latest_invoice_Amount_Z_Score_to_invoice_Amount_28d | \n",
" 31e54300 | \n",
"
\n",
" \n",
" 6 | \n",
" CUSTOMER_Std_of_invoice_Amount_14d | \n",
" 31e54300 | \n",
"
\n",
" \n",
" 7 | \n",
" CUSTOMER_vs_OVERALL_item_TotalCost_across_product_ProductGroups_26w | \n",
" f831676d | \n",
"
\n",
" \n",
" 8 | \n",
" CUSTOMER_vs_OVERALL_item_TotalCost_across_product_ProductGroups_26w | \n",
" c5e9a3c5 | \n",
"
\n",
" \n",
"
\n",
"
\n",
" \n",
" \n",
" | \n",
" aggregation_hash | \n",
" frequency(min) | \n",
" completed_jobs | \n",
" max_duration(s) | \n",
" 95 percentile | \n",
" frac_late | \n",
" exceed_period | \n",
" failed_jobs | \n",
" incomplete_jobs | \n",
" time_since_last | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 0ee300b2 | \n",
" 60 | \n",
" 0 | \n",
" NaN | \n",
" NaN | \n",
" NaN | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" NaT | \n",
"
\n",
" \n",
" 1 | \n",
" 7cee376c | \n",
" 60 | \n",
" 0 | \n",
" NaN | \n",
" NaN | \n",
" NaN | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" NaT | \n",
"
\n",
" \n",
" 2 | \n",
" 45351576 | \n",
" 60 | \n",
" 0 | \n",
" NaN | \n",
" NaN | \n",
" NaN | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" NaT | \n",
"
\n",
" \n",
" 3 | \n",
" 31e54300 | \n",
" 60 | \n",
" 0 | \n",
" NaN | \n",
" NaN | \n",
" NaN | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" NaT | \n",
"
\n",
" \n",
" 4 | \n",
" f831676d | \n",
" 60 | \n",
" 0 | \n",
" NaN | \n",
" NaN | \n",
" NaN | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" NaT | \n",
"
\n",
" \n",
" 5 | \n",
" c5e9a3c5 | \n",
" 60 | \n",
" 0 | \n",
" NaN | \n",
" NaN | \n",
" NaN | \n",
" 0 | \n",
" 0 | \n",
" 1 | \n",
" NaT | \n",
"
\n",
" \n",
"
\n",
"

\n",
"

\n",
"
"
],
"text/plain": [
" request_date job_history_window job_duration_tolerance\n",
"0 2023-11-27T15:47:48.386771 1 60\n",
"\n",
" feature_name aggregation_hash\n",
"0 CUSTOMER_Avg_of_invoice_Amount_14d 45351576\n",
"1 CUSTOMER_Count_of_invoice_14d 7cee376c\n",
"2 CUSTOMER_Latest_invoice_Amount 0ee300b2\n",
"3 CUSTOMER_Latest_invoice_Amount_Z_Score_to_invo... 0ee300b2\n",
"4 CUSTOMER_Latest_invoice_Amount_Z_Score_to_invo... 45351576\n",
"5 CUSTOMER_Latest_invoice_Amount_Z_Score_to_invo... 31e54300\n",
"6 CUSTOMER_Std_of_invoice_Amount_14d 31e54300\n",
"7 CUSTOMER_vs_OVERALL_item_TotalCost_across_prod... f831676d\n",
"8 CUSTOMER_vs_OVERALL_item_TotalCost_across_prod... c5e9a3c5\n",
"\n",
" aggregation_hash frequency(min) completed_jobs max_duration(s) \\\n",
"0 0ee300b2 60 0 NaN \n",
"1 7cee376c 60 0 NaN \n",
"2 45351576 60 0 NaN \n",
"3 31e54300 60 0 NaN \n",
"4 f831676d 60 0 NaN \n",
"5 c5e9a3c5 60 0 NaN \n",
"\n",
" 95 percentile frac_late exceed_period failed_jobs incomplete_jobs \\\n",
"0 NaN NaN 0 0 1 \n",
"1 NaN NaN 0 0 1 \n",
"2 NaN NaN 0 0 1 \n",
"3 NaN NaN 0 0 1 \n",
"4 NaN NaN 0 0 1 \n",
"5 NaN NaN 0 0 1 \n",
"\n",
" time_since_last \n",
"0 NaT \n",
"1 NaT \n",
"2 NaT \n",
"3 NaT \n",
"4 NaT \n",
"5 NaT "
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# get feature jobs status (this will produce meaningful results once multiple jobs have been run)\n",
"deployment.get_feature_jobs_status()"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "eb75a9fc",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done! |████████████████████████████████████████| 100% in 9.8s (0.10%/s) \n"
]
}
],
"source": [
"# Disable deployment\n",
"deployment.disable()"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "26f28433",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" id | \n",
" name | \n",
" feature_list_name | \n",
" feature_list_version | \n",
" num_feature | \n",
" enabled | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 6564b9c77927bf2a9d6cca65 | \n",
" Customer Spending forecast | \n",
" Customer Simple FeatureList | \n",
" V231127 | \n",
" 7 | \n",
" False | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" id name \\\n",
"0 6564b9c77927bf2a9d6cca65 Customer Spending forecast \n",
"\n",
" feature_list_name feature_list_version num_feature enabled \n",
"0 Customer Simple FeatureList V231127 7 False "
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# The deployment is still part of the catalog but disabled\n",
"catalog.list_deployments()"
]
},
{
"cell_type": "markdown",
"id": "4b005f3e",
"metadata": {},
"source": [
"### Concepts in this tutorial\n",
"- [Feature list deployment](https://docs.featurebyte.com/latest/about/glossary/#feature-list-deployment)\n",
"- [REST API and batch serving](https://docs.featurebyte.com/latest/about/glossary/#online-and-batch-serving)\n",
"- [Feature jobs](https://docs.featurebyte.com/latest/about/glossary/#feature-jobs)\n",
"\n",
"#### SDK reference for\n",
"- [Deployment](https://docs.featurebyte.com/latest/reference/core/deployment/)\n",
"- [Batch Request Table](https://docs.featurebyte.com/latest/reference/core/batch_request_table/)\n",
"- [Batch Feature Table](https://docs.featurebyte.com/latest/reference/core/batch_feature_table/)\n",
"- [FeatureList.deploy()](https://docs.featurebyte.com/latest/reference/featurebyte.api.feature_list.FeatureList.deploy/) \n",
"- [Deployment.enable()](https://docs.featurebyte.com/latest/reference/featurebyte.api.deployment.Deployment.enable/)\n",
"- [Deployment.get_online_serving_code()](https://docs.featurebyte.com/latest/reference/featurebyte.api.deployment.Deployment.get_online_serving_code/)\n",
"- [Deployment.compute batch feature_table()](https://docs.featurebyte.com/latest/reference/featurebyte.api.deployment.Deployment.compute_batch_feature_table/)\n",
"- [Table.get_view()](https://docs.featurebyte.com/latest/reference/featurebyte.api.scd_table.SCDTable.get_view/) in a manual mode\n",
"- [View.create_batch_request_table()](https://docs.featurebyte.com/latest/reference/featurebyte.api.view.View.create_batch_request_table/)\n",
"- [SourceTable.create_batch_request_table()](https://docs.featurebyte.com/latest/reference/featurebyte.api.source_table.SourceTable.create_batch_request_table/)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f50df3b4",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}