Repository: feast-dev/feast

Issue:
FeatureStore._plan should be a public method
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

https://github.com/feast-dev/feast/blob/master/sdk/python/feast/feature_store.py#L639

Ideally, all FeatureStore methods that back a CLI operation should have a public facing programatic API. In this case, `feast plan` users `FeatureStore._plan` -> which signifies that it should be treated as a private method.

**Describe the solution you'd like**
The change would be as simple as refactoring it to `FeatureStore.plan`.





Discussion:
cc @chhabrakadabra 

Resolving patch:
diff --git a/sdk/python/feast/feature_store.py b/sdk/python/feast/feature_store.py
--- a/sdk/python/feast/feature_store.py
+++ b/sdk/python/feast/feature_store.py
@@ -511,8 +511,8 @@ def _get_features(
         return _feature_refs
 
     def _should_use_plan(self):
-        """Returns True if _plan and _apply_diffs should be used, False otherwise."""
-        # Currently only the local provider with sqlite online store supports _plan and _apply_diffs.
+        """Returns True if plan and _apply_diffs should be used, False otherwise."""
+        # Currently only the local provider with sqlite online store supports plan and _apply_diffs.
         return self.config.provider == "local" and (
             self.config.online_store and self.config.online_store.type == "sqlite"
         )
@@ -636,7 +636,7 @@ def _get_feature_views_to_materialize(
         return feature_views_to_materialize
 
     @log_exceptions_and_usage
-    def _plan(
+    def plan(
         self, desired_repo_contents: RepoContents
     ) -> Tuple[RegistryDiff, InfraDiff, Infra]:
         """Dry-run registering objects to metadata store.
@@ -670,7 +670,7 @@ def _plan(
             ...     ttl=timedelta(seconds=86400 * 1),
             ...     batch_source=driver_hourly_stats,
             ... )
-            >>> registry_diff, infra_diff, new_infra = fs._plan(RepoContents(
+            >>> registry_diff, infra_diff, new_infra = fs.plan(RepoContents(
             ...     data_sources=[driver_hourly_stats],
             ...     feature_views=[driver_hourly_stats_view],
             ...     on_demand_feature_views=list(),
diff --git a/sdk/python/feast/repo_operations.py b/sdk/python/feast/repo_operations.py
--- a/sdk/python/feast/repo_operations.py
+++ b/sdk/python/feast/repo_operations.py
@@ -183,7 +183,7 @@ def plan(repo_config: RepoConfig, repo_path: Path, skip_source_validation: bool)
         for data_source in data_sources:
             data_source.validate(store.config)
 
-    registry_diff, infra_diff, _ = store._plan(repo)
+    registry_diff, infra_diff, _ = store.plan(repo)
     click.echo(registry_diff.to_string())
     click.echo(infra_diff.to_string())
 
@@ -262,7 +262,7 @@ def apply_total_with_repo_instance(
         for data_source in data_sources:
             data_source.validate(store.config)
 
-    registry_diff, infra_diff, new_infra = store._plan(repo)
+    registry_diff, infra_diff, new_infra = store.plan(repo)
 
     # For each object in the registry, determine whether it should be kept or deleted.
     (


Test patch: