Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Fix issue when user specifies a port for feast ui #2692

Merged
merged 4 commits into from
May 16, 2022
Merged
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
18 changes: 5 additions & 13 deletions sdk/python/feast/ui/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 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.
This is an example React App that imports the Feast UI module.

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

Expand All @@ -11,23 +11,15 @@ 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();
})
}}
/>
<FeastUI />
</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
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.`

The `feast ui` command will generate the necessary `projects-list.json` file and initialize it for the UI to read.


**Note**: yarn start will not work on this because of the above dependency.
11 changes: 11 additions & 0 deletions sdk/python/feast/ui/public/projects-list.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
adchia marked this conversation as resolved.
Show resolved Hide resolved
"projects": [
{
"name": "Project",
"description": "Test project",
"id": "project_id",
"registryPath": "http://0.0.0.0:8888/registry"
}
]
}

18 changes: 4 additions & 14 deletions sdk/python/feast/ui/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
import React from 'react';
import React from "react";
import ReactDOM from "react-dom";
import './index.css';
import "./index.css";
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();
})
}}
/>
<FeastUI />
</React.StrictMode>,
document.getElementById("root")
);
);
27 changes: 13 additions & 14 deletions sdk/python/feast/ui_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ def get_app(
get_registry_dump: Callable,
project_id: str,
registry_ttl_secs: int,
host: str,
port: int,
):
ui_dir = pkg_resources.resource_filename(__name__, "ui/build/")

app = FastAPI()

app.add_middleware(
Expand Down Expand Up @@ -53,25 +53,24 @@ def shutdown_event():

async_refresh()

@app.get("/registry")
def read_registry():
return json.loads(registry_json)

# Generate projects-list json that points to the current repo's project
# TODO(adchia): Enable users to also add project name + description fields in feature_store.yaml
@app.get("/projects-list")
def projects_list():
projects = {
ui_dir = pkg_resources.resource_filename(__name__, "ui/build/")
# Initialize with the projects-list.json file
with open(ui_dir + "projects-list.json", mode="w") as f:
projects_dict = {
"projects": [
{
"name": "Project",
"description": "Test project",
"id": project_id,
"registryPath": "http://0.0.0.0:8888/registry",
"registryPath": f"http://{host}:{port}/registry",
}
]
}
return projects
f.write(json.dumps(projects_dict))

@app.get("/registry")
def read_registry():
return json.loads(registry_json)

# For all other paths (such as paths that would otherwise be handled by react router), pass to React
@app.api_route("/p/{path_name:path}", methods=["GET"])
Expand All @@ -98,5 +97,5 @@ def start_server(
project_id: str,
registry_ttl_sec: int,
):
app = get_app(store, get_registry_dump, project_id, registry_ttl_sec)
app = get_app(store, get_registry_dump, project_id, registry_ttl_sec, host, port)
uvicorn.run(app, host=host, port=port)