Skip to content

Commit

Permalink
feat: Allow Feast UI to be spun up with CLI command: feast ui (#2667)
Browse files Browse the repository at this point in the history
Signed-off-by: Danny Chiao <danny@tecton.ai>
  • Loading branch information
adchia authored May 11, 2022
1 parent d4b0b1a commit 44ca9f5
Show file tree
Hide file tree
Showing 29 changed files with 38,843 additions and 16 deletions.
14 changes: 13 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ jobs:
os: [ ubuntu-latest, macos-10.15 ]
steps:
- uses: actions/checkout@v2
- name: Setup Node
uses: actions/setup-node@v2
with:
node-version: '17.x'
registry-url: 'https://registry.npmjs.org'
- name: Build wheels
uses: pypa/cibuildwheel@v2.4.0
env:
Expand All @@ -183,6 +188,7 @@ jobs:
make install-protoc-dependencies
make install-go-proto-dependencies
make install-go-ci-dependencies
make build-ui
- uses: actions/upload-artifact@v2
with:
Expand All @@ -202,12 +208,18 @@ jobs:
with:
python-version: "3.10"
architecture: x64
- name: Install dependencies
- name: Setup Node
uses: actions/setup-node@v2
with:
node-version: '17.x'
registry-url: 'https://registry.npmjs.org'
- name: Build and install dependencies
run: |
pip install -U pip setuptools wheel twine
make install-protoc-dependencies
make install-go-proto-dependencies
make install-go-ci-dependencies
make build-ui
- name: Build
run: |
python3 setup.py sdist bdist_wheel
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ go/protos/


# Feast UI dependencies
sdk/python/feast/ui/node_modules
sdk/python/feast/ui/build
ui/node_modules
ui/.pnp
ui/.pnp.js
Expand Down
7 changes: 6 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,12 @@ source venv/bin/activate
pip install --upgrade pip
```

4. Install development dependencies for Feast Python SDK / CLI
4. (Optional): Install Node & Yarn. Then run the following to build Feast UI artifacts for use in `feast ui`
```
make build-ui
```

5Install development dependencies for Feast Python SDK / CLI
```sh
pip install -e ".[dev]"
```
Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,9 @@ build-sphinx: compile-protos-python

build-templates:
python infra/scripts/compile-templates.py

# Web UI

# Note: requires node and yarn to be installed
build-ui:
cd $(ROOT_DIR)/sdk/python/feast/ui && yarn install && npm run build --omit=dev
2 changes: 1 addition & 1 deletion sdk/python/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,4 @@ dmypy.json
.pyre/

.vscode/*
playground
playground
15 changes: 14 additions & 1 deletion sdk/python/feast/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,19 @@ def version():
print(f'Feast SDK Version: "{pkg_resources.get_distribution("feast")}"')


@cli.command()
@click.pass_context
def ui(ctx: click.Context):
"""
Shows the Feast UI over the current directory
"""
repo = ctx.obj["CHDIR"]
cli_check_repo(repo)
store = FeatureStore(repo_path=str(repo))
repo_config = load_repo_config(repo)
store.serve_ui(registry_dump(repo_config, repo_path=repo))


@cli.command()
@click.pass_context
def endpoint(ctx: click.Context):
Expand Down Expand Up @@ -475,7 +488,7 @@ def registry_dump_command(ctx: click.Context):
cli_check_repo(repo)
repo_config = load_repo_config(repo)

registry_dump(repo_config, repo_path=repo)
click.echo(registry_dump(repo_config, repo_path=repo))


@cli.command("materialize")
Expand Down
12 changes: 11 additions & 1 deletion sdk/python/feast/feature_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from google.protobuf.timestamp_pb2 import Timestamp
from tqdm import tqdm

from feast import feature_server, flags, flags_helper, utils
from feast import feature_server, flags, flags_helper, ui_server, utils
from feast.base_feature_view import BaseFeatureView
from feast.data_source import DataSource
from feast.diff.infra_diff import InfraDiff, diff_infra_protos
Expand Down Expand Up @@ -1985,6 +1985,16 @@ def get_feature_server_endpoint(self) -> Optional[str]:
"""Returns endpoint for the feature server, if it exists."""
return self._provider.get_feature_server_endpoint()

@log_exceptions_and_usage
def serve_ui(self, registry_dump: str) -> None:
"""Start the UI server locally"""
warnings.warn(
"The Feast UI is an experimental feature. "
"We do not guarantee that future changes will maintain backward compatibility.",
RuntimeWarning,
)
ui_server.start_server(self, registry_dump, self.config.project)

@log_exceptions_and_usage
def serve_transformations(self, port: int) -> None:
"""Start the feature transformation server locally on a given port."""
Expand Down
5 changes: 2 additions & 3 deletions sdk/python/feast/repo_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,14 +281,13 @@ def teardown(repo_config: RepoConfig, repo_path: Path):


@log_exceptions_and_usage
def registry_dump(repo_config: RepoConfig, repo_path: Path):
def registry_dump(repo_config: RepoConfig, repo_path: Path) -> str:
"""For debugging only: output contents of the metadata registry"""
registry_config = repo_config.get_registry_config()
project = repo_config.project
registry = Registry(registry_config=registry_config, repo_path=repo_path)
registry_dict = registry.to_dict(project=project)

click.echo(json.dumps(registry_dict, indent=2, sort_keys=True))
return json.dumps(registry_dict, indent=2, sort_keys=True)


def cli_check_repo(repo_path: Path):
Expand Down
33 changes: 33 additions & 0 deletions sdk/python/feast/ui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Example Feast UI App

This is an example React App that imports the Feast UI module and relies on a "/projects-list" endpoint to get projects.

See the module import in `src/index.js`. The main change this implements on top of a vanilla create-react-app is adding:

```tsx
import ReactDOM from "react-dom";
import FeastUI from "@feast-dev/feast-ui";
import "@feast-dev/feast-ui/dist/feast-ui.css";

ReactDOM.render(
<React.StrictMode>
<FeastUI
feastUIConfigs={{
projectListPromise: fetch("http://0.0.0.0:8888/projects-list", {
headers: {
"Content-Type": "application/json",
},
}).then((res) => {
return res.json();
})
}}
/>
</React.StrictMode>,
document.getElementById("root")
);
```

It is used by the `feast ui` command to scaffold a local UI server. The feast python package bundles in resources produced from `npm run build --omit=dev


**Note**: yarn start will not work on this because of the above dependency.
File renamed without changes.
Loading

0 comments on commit 44ca9f5

Please sign in to comment.