Creates a FastAPI app that can be used to start a feature server. Args: store: The FeatureStore to use for serving features registry_ttl_sec: The TTL in seconds for the registry cache Returns: A FastAPI app Example: ```python from feast imp
(
store: "feast.FeatureStore",
registry_ttl_sec: int = DEFAULT_FEATURE_SERVER_REGISTRY_TTL,
)
| 301 | |
| 302 | |
| 303 | def get_app( |
| 304 | store: "feast.FeatureStore", |
| 305 | registry_ttl_sec: int = DEFAULT_FEATURE_SERVER_REGISTRY_TTL, |
| 306 | ): |
| 307 | """ |
| 308 | Creates a FastAPI app that can be used to start a feature server. |
| 309 | |
| 310 | Args: |
| 311 | store: The FeatureStore to use for serving features |
| 312 | registry_ttl_sec: The TTL in seconds for the registry cache |
| 313 | |
| 314 | Returns: |
| 315 | A FastAPI app |
| 316 | |
| 317 | Example: |
| 318 | ```python |
| 319 | from feast import FeatureStore |
| 320 | |
| 321 | store = FeatureStore(repo_path="feature_repo") |
| 322 | app = get_app(store) |
| 323 | ``` |
| 324 | |
| 325 | The app provides the following endpoints: |
| 326 | - `/get-online-features`: Get online features |
| 327 | - `/retrieve-online-documents`: Retrieve online documents |
| 328 | - `/push`: Push features to the feature store |
| 329 | - `/write-to-online-store`: Write to the online store |
| 330 | - `/health`: Health check |
| 331 | - `/materialize`: Materialize features |
| 332 | - `/materialize-incremental`: Materialize features incrementally |
| 333 | - `/chat`: Chat UI |
| 334 | - `/ws/chat`: WebSocket endpoint for chat |
| 335 | MCP Support: |
| 336 | - If MCP is enabled in feature server configuration, MCP endpoints will be added automatically |
| 337 | """ |
| 338 | proto_json.patch() |
| 339 | # Asynchronously refresh registry, notifying shutdown and canceling the active timer if the app is shutting down |
| 340 | shutting_down = False |
| 341 | active_timer: Optional[threading.Timer] = None |
| 342 | # --- Offline write batching config and batcher --- |
| 343 | fs_cfg = getattr(store.config, "feature_server", None) |
| 344 | batching_cfg = None |
| 345 | if fs_cfg is not None: |
| 346 | enabled = getattr(fs_cfg, "offline_push_batching_enabled", False) |
| 347 | batch_size = getattr(fs_cfg, "offline_push_batching_batch_size", None) |
| 348 | batch_interval_seconds = getattr( |
| 349 | fs_cfg, "offline_push_batching_batch_interval_seconds", None |
| 350 | ) |
| 351 | |
| 352 | if enabled is True: |
| 353 | size_ok = isinstance(batch_size, int) and not isinstance(batch_size, bool) |
| 354 | interval_ok = isinstance(batch_interval_seconds, int) and not isinstance( |
| 355 | batch_interval_seconds, bool |
| 356 | ) |
| 357 | if size_ok and interval_ok: |
| 358 | batching_cfg = SimpleNamespace( |
| 359 | enabled=True, |
| 360 | batch_size=batch_size, |