Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
* [RAG Fine Tuning with Feast and Milvus](../examples/rag-retriever/README.md)
* [MCP - AI Agent Example](../examples/mcp_feature_store/README.md)
* [Feast-Powered AI Agent](../examples/agent_feature_store/README.md)
* [Demo Notebooks](tutorials/demo-notebooks.md)

## How-to Guides

Expand Down
1 change: 1 addition & 0 deletions docs/getting-started/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,7 @@ show up in the upcoming concepts + architecture + tutorial pages as well.

## Next steps

* Run `feast demo-notebooks` to generate tailored Jupyter notebooks for your project. See [Demo Notebooks](../tutorials/demo-notebooks.md).
* Read the [Concepts](concepts/) page to understand the Feast data model.
* Read the [Architecture](architecture/) page.
* Check out our [Tutorials](../tutorials/tutorials-overview/) section for more examples on how to use Feast.
Expand Down
42 changes: 42 additions & 0 deletions docs/reference/feast-cli-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Commands:
apply Create or update a feature store deployment
configuration Display Feast configuration
delete Delete a Feast object from the registry
demo-notebooks Generate demo Jupyter notebooks for the project
entities Access entities
feature-views Access feature views
init Create a new Feast repository
Expand Down Expand Up @@ -142,6 +143,47 @@ The delete operation is permanent and will remove the object from the registry.
If multiple objects have the same name across different types, `feast delete` will delete the first one it finds. For programmatic deletion with more control, use the Python SDK methods like `store.delete_feature_view()`, `store.delete_feature_service()`, etc.
{% endhint %}

## Demo Notebooks

Generate tailored demo Jupyter notebooks for each Feast project found in the current directory.

```bash
feast demo-notebooks
```

The command searches for `feature_store.yaml` in the current directory and every file inside the `feast-config/` directory. Each file is treated as a separate project config, and notebooks are created under `./feast-demo-notebooks/<project>/`.

The generated notebooks adapt to your project configuration (online/offline store types, authentication, vector search) and cover:

* **Feature store overview** — explore registered entities, feature views, and services.
* **Historical feature retrieval** — build training datasets with point-in-time correct joins.
* **Online feature serving** — materialize features and retrieve them at low latency.

**Options:**

* `-o, --output-dir` — Directory where the notebooks are written. Default: `./feast-demo-notebooks`.
* `--overwrite` — Overwrite existing notebooks if the output directory already exists.

```bash
feast demo-notebooks -o ./my-notebooks --overwrite
```

You can also use the `--chdir` global option to point at a different feature repository:

```bash
feast -c /path/to/feature_repo demo-notebooks
```

The same functionality is available via the Python SDK:

```python
from feast import copy_demo_notebooks

copy_demo_notebooks(output_dir="./feast-demo-notebooks", repo_path=".")
```

For more details see the [Demo Notebooks tutorial](../tutorials/demo-notebooks.md).

## Entities

List all registered entities
Expand Down
114 changes: 114 additions & 0 deletions docs/tutorials/demo-notebooks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Demo Notebooks

Feast can generate tailored Jupyter notebooks for any Feast project. The notebooks adapt to your `feature_store.yaml` configuration and provide a hands-on walkthrough of core Feast functionality.

## What you get

For each project discovered, Feast creates a directory with notebooks covering:

| Notebook | Description |
|----------|-------------|
| **01 — Feature Store Overview** | Explore registered entities, feature views, feature services, and data sources. |
| **02 — Historical Feature Retrieval** | Build a training dataset with point-in-time correct joins using `get_historical_features`. |
| **03 — Online Feature Serving** | Materialize features to the online store and retrieve them at low latency with `get_online_features`. |

The content adapts automatically based on:

* **Online / offline store types** — descriptions reflect the actual backends configured.
* **Registry type** — local registries include `feast apply`; remote registries use `refresh_registry()`.
* **Authentication** — auth details from `feature_store.yaml` are surfaced when configured.
* **Vector search** — a vector/RAG retrieval section is included when embeddings are detected.

## Prerequisites

* Python 3.9+
* Feast installed (`pip install feast`)
* A feature repository with a valid `feature_store.yaml`

## Using the CLI

Run the command from (or pointing to) a directory containing `feature_store.yaml`:

```bash
feast demo-notebooks
```

This searches for `feature_store.yaml` in the current directory and every file inside the `feast-config/` directory. Each file in `feast-config/` is treated as a separate project config. For each project found, notebooks are written to `./feast-demo-notebooks/<project>/`.

### Options

| Option | Default | Description |
|--------|---------|-------------|
| `-o, --output-dir` | `./feast-demo-notebooks` | Root directory for generated notebooks |
| `--overwrite` | `false` | Overwrite if the output directory already exists |

```bash
# Write to a custom directory
feast demo-notebooks -o ./my-notebooks

# Overwrite existing notebooks
feast demo-notebooks --overwrite

# Use --chdir to point at a different feature repo
feast -c /path/to/feature_repo demo-notebooks
```

## Using the Python SDK

```python
from feast import copy_demo_notebooks

copy_demo_notebooks()
```

### Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `output_dir` | `str` | `"./feast-demo-notebooks"` | Root directory for generated notebooks |
| `repo_path` | `str` | `"."` | Directory to search for `feature_store.yaml` files |
| `overwrite` | `bool` | `False` | Overwrite existing output directories |

### Examples

```python
from feast import copy_demo_notebooks

# Default — searches current directory, writes to ./feast-demo-notebooks/
copy_demo_notebooks()

# Custom paths
copy_demo_notebooks(
output_dir="/home/user/notebooks",
repo_path="/home/user/feast-projects/my-repo/feature_repo",
overwrite=True,
)
```

## Multi-project repositories

If your `feast-config/` directory contains multiple files, each is treated as a separate project and a dedicated notebook directory is created:

```
feast-demo-notebooks/
├── project_alpha/
│ ├── 01_feature_store_overview.ipynb
│ ├── 02_historical_features_training.ipynb
│ └── 03_online_features_serving.ipynb
└── project_beta/
├── 01_feature_store_overview.ipynb
├── 02_historical_features_training.ipynb
└── 03_online_features_serving.ipynb
```

## Running the notebooks

Open any generated notebook in Jupyter, JupyterLab, or VS Code and run cells from top to bottom. Each notebook:

1. Configures the path to your `feature_store.yaml` automatically (no manual editing needed).
2. Connects to the feature store using the Feast Python SDK.
3. Walks through relevant operations with real data from your project.

{% hint style="info" %}
The first notebook (**01 — Overview**) includes a prerequisites check and `feast apply` / registry sync step. Subsequent notebooks assume these have already been completed.
{% endhint %}
6 changes: 3 additions & 3 deletions pixi.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions sdk/python/docs/source/feast.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ feast.data\_format module
:undoc-members:
:show-inheritance:

feast.demos module
------------------

.. automodule:: feast.demos
:members:
:undoc-members:
:show-inheritance:

feast.data\_source module
-------------------------

Expand Down
2 changes: 2 additions & 0 deletions sdk/python/feast/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from importlib.metadata import PackageNotFoundError
from importlib.metadata import version as _version

from feast.demos import copy_demo_notebooks
from feast.infra.offline_stores.bigquery_source import BigQuerySource
from feast.infra.offline_stores.contrib.athena_offline_store.athena_source import (
AthenaSource,
Expand Down Expand Up @@ -41,6 +42,7 @@
__all__ = [
"Aggregation",
"BatchFeatureView",
"copy_demo_notebooks",
"DataFrameEngine",
"Entity",
"KafkaSource",
Expand Down
33 changes: 33 additions & 0 deletions sdk/python/feast/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,39 @@ def validate(
exit(1)


@cli.command("demo-notebooks")
@click.option(
"--output-dir",
"-o",
default="./feast-demo-notebooks",
show_default=True,
help="Directory where the demo notebooks are written.",
)
@click.option(
"--overwrite",
is_flag=True,
default=False,
help="Overwrite existing notebooks if the output directory already exists.",
)
@click.pass_context
def demo_notebooks_command(ctx: click.Context, output_dir: str, overwrite: bool):
"""
Generate demo Jupyter notebooks tailored to the feature store configuration.

Searches for feature_store.yaml in the current directory and every file
inside feast-config/. Each file is treated as a separate project config.
For each project found, a sub-directory is created under OUTPUT_DIR.
"""
from feast.demos import copy_demo_notebooks

repo = ctx.obj["CHDIR"]
copy_demo_notebooks(
output_dir=output_dir,
repo_path=str(repo),
overwrite=overwrite,
)


cli.add_command(data_sources_cmd)
cli.add_command(entities_cmd)
cli.add_command(feature_services_cmd)
Expand Down
Loading
Loading