<jupyter_start><jupyter_text>Demo of running a Flyte + Feast, feature engineering and training pipelineIn this demo we will learn how to interact with Feast through Flyte. The goal will be to train a simple [Gaussian Naive Bayes model using sklearn](https://scikit-learn.org/stable/modules/generated/sklearn.naive_bayes.GaussianNB.html) on the [Horse-Colic dataset from UCI](https://archive.ics.uci.edu/ml/datasets/Horse+Colic).The model aims to classify if the lesion of the horse is surgical or not. This is a modified version of the original dataset.**NOTE**We will not really dive into the dataset or the model, as the aim of this tutorial is to show how you can use Feast as the feature store and use Flyte to engineer the features that can be identical across your online predictions as well as offline training  Step 1: Check out the code for the pipelineWe have used [flytekit](https://docs.flyte.org/projects/flytekit/en/latest/) flyte's python SDK to express the pipeline in pure python. The actual workflow code is auto-documented and rendered using sphinx [here](https://flyte--424.org.readthedocs.build/projects/cookbook/en/424/auto/case_studies/feature_engineering/feast_integration/index.html) *to be merged soon*  Step 2: Launch an executionWe can use the [FlyteConsole](https://github.com/flyteorg/flyteconsole) to launch, monitor and introspect Flyte executions, but in this case we will use [flytekit.remote](https://docs.flyte.org/projects/flytekit/en/latest/design/control_plane.html) to interact with the Flyte backend. Setup flytekit remote from configTo work with flytesandbox, we have created a simple local config that points to FlyteSandbox server and execution environment. We will initialize flytekit remote with this server. We will also pin it to one project and domain.**Note** this also sets up access to S3 or other equivalent datastores needed by FEAST<jupyter_code>from flytekit.remote import FlyteRemote
remote = FlyteRemote.from_config("flytesnacks", "development")<jupyter_output><empty_output><jupyter_text>Retrieve the latest registered version of the pipelineFlyteRemote provides convienient methods to retrieve a version of the pipeline from the remote server.**Note** It is possible to get a specific version of workflow and trigger a launch for that, but, we will just get the latest<jupyter_code># from feast_integration.feast_workflow import feast_workflow
lp = remote.fetch_launch_plan(name="feast_integration.feast_workflow.feast_workflow")
lp.id.version<jupyter_output><empty_output><jupyter_text>Launch an execution`remote.execute` makes it simple to start an execution for the launchplan. We will not provide any inputs and just use the default inputs<jupyter_code>exe = remote.execute(lp, inputs={})
print(f"http://localhost:30081/console/projects/{exe.id.project}/domains/{exe.id.domain}/executions/{exe.id.name}")<jupyter_output><empty_output><jupyter_text>Step 3: Now wait for the execution to completeIt is possible to launch a sync execution and wait for it to complete, but since all the processes are completely detached (you can even close your laptop) and come back to it later, we will show how to sync the execution back.<jupyter_code>from flytekit.models.core.execution import WorkflowExecutionPhase
exe = remote.sync(exe)
print(f"Execution {exe.id.name} is in Phase - {WorkflowExecutionPhase.enum_to_string(exe.closure.phase)}")
exe.sync()<jupyter_output><empty_output><jupyter_text>Step 4: Lets sync data from this execution**Side Note**It is possible to fetch an existing execution or simply retrieve a started execution. Also if you launch an execution with the same name, flyte will respect and not restart a new execution!To fetch an execution```pythonexe = remote.fetch_workflow_execution(name='f9f180a56e67b4c9781e')exe = remote.sync(exe)```<jupyter_code>from feast_dataobjects import FeatureStore
fs = exe.raw_outputs.get('o0', FeatureStore)
model = exe.outputs['o1']<jupyter_output><empty_output><jupyter_text>Lets inspect the feature store configuration<jupyter_code>fs.config<jupyter_output><empty_output><jupyter_text>Also, the model is now available locally as a JobLibSerialized file and can be downloaded and loaded<jupyter_code>model<jupyter_output><empty_output><jupyter_text>Step 5: Cool, Let's predictSo we have the model and a feature store!, how can you run predictions. Flytekit will automatically manage the IO for you and you can simply re-use the prediction function from the workflow.  Lets load some features from the online feature storeWe are re-using the feature definition from the flyte workflow```pythoninference_point = fs.get_online_features(FEAST_FEATURES, [{"Hospital Number": "533738"}])```<jupyter_code>from feast_workflow import predict, FEAST_FEATURES
inference_point = fs.get_online_features(FEAST_FEATURES, [{"Hospital Number": "533738"}])
inference_point<jupyter_output><empty_output><jupyter_text>Now run a predictionNotice how we are passing the serialized model and some loaded features<jupyter_code>predict(model_ser=model, features=inference_point)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07618299626938936, 'fraction_numerical': 0.008639308855291577, 'mean_word_length': 6.5022091310751104, 'pattern_counts': {'":': 2, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '397405', 'license': 'Apache-2.0', 'n_tokens_mistral': 1507, 'n_tokens_neox': 1428, 'n_words': 539, 'path': 'cookbook/case_studies/feature_engineering/feast_integration/Feast_Flyte_Demo.ipynb', 'repo_name': 'YmirKhang/flytesnacks', 'size': '5093'}