(info: dict[str, Any], yaml_abs: str)
| 528 | |
| 529 | |
| 530 | def _nb_online(info: dict[str, Any], yaml_abs: str) -> dict[str, Any]: |
| 531 | project = info["project"] |
| 532 | auth = info["auth_type"] |
| 533 | vector_enabled = info["vector_enabled"] |
| 534 | |
| 535 | cells: list[dict[str, Any]] = [ |
| 536 | _md( |
| 537 | f"# Online Feature Serving — `{project}`\n\n" |
| 538 | "Materialize features and retrieve them at low latency for inference." |
| 539 | ), |
| 540 | _md("## 1. Feature Store Path"), |
| 541 | _path_setup_cell(yaml_abs), |
| 542 | _md("## 2. Connect to the Feature Store"), |
| 543 | _code( |
| 544 | "from feast import FeatureStore\n" |
| 545 | "\n" |
| 546 | "store = FeatureStore(fs_yaml_file=FEAST_FS_YAML)\n" |
| 547 | "print(f'Project : {store.project}')" |
| 548 | ), |
| 549 | ] |
| 550 | |
| 551 | # Materialization section. |
| 552 | materialize_md = ( |
| 553 | "## 3. Materialize Features\n\n" |
| 554 | + ( |
| 555 | "> **Optional** — materialization is typically handled server-side.\n\n" |
| 556 | if _is_operator_client(info) |
| 557 | else "" |
| 558 | ) |
| 559 | + "Load feature values into the online store for low-latency serving.\n\n" |
| 560 | "| Method | When to use |\n" |
| 561 | "|--------|-------------|\n" |
| 562 | "| `materialize_incremental` | Regular runs — only new data since last run |\n" |
| 563 | "| `materialize` | First run or full refresh of a time window |" |
| 564 | ) |
| 565 | cells += [ |
| 566 | _md(materialize_md), |
| 567 | _code( |
| 568 | "from datetime import datetime, timedelta, timezone\n" |
| 569 | "\n" |
| 570 | "fvs = store.list_feature_views()\n" |
| 571 | "\n" |
| 572 | "if not fvs:\n" |
| 573 | " print('No feature views found — run feast apply first (see section 3).')\n" |
| 574 | "else:\n" |
| 575 | " # Check last materialization watermarks across all feature views.\n" |
| 576 | " last_written = [\n" |
| 577 | " fv.materialization_intervals[-1][1]\n" |
| 578 | " for fv in fvs\n" |
| 579 | " if fv.materialization_intervals\n" |
| 580 | " ]\n" |
| 581 | "\n" |
| 582 | " if not last_written:\n" |
| 583 | " # No materialization history — do a full initial load.\n" |
| 584 | " end_date = datetime.now(tz=timezone.utc)\n" |
| 585 | " start_date = end_date - timedelta(days=30)\n" |
| 586 | " print(f'First materialization: loading {start_date.date()} → {end_date.date()} ...')\n" |
| 587 | " store.materialize(start_date=start_date, end_date=end_date)\n" |
no test coverage detected