From 00a9de92b818723acaf843f2d1e433d194949ad8 Mon Sep 17 00:00:00 2001 From: Danny Chiao Date: Mon, 16 May 2022 15:24:52 -0400 Subject: [PATCH] fix: Fix issue when user specifies a port for feast ui (#2692) * fix: Fix issue when user specifies a port for feast ui Signed-off-by: Danny Chiao * fx Signed-off-by: Danny Chiao * fix python 3.9 version of importlib Signed-off-by: Danny Chiao * revert to pkg_resources Signed-off-by: Danny Chiao --- sdk/python/feast/ui/README.md | 18 ++++--------- sdk/python/feast/ui/public/projects-list.json | 11 ++++++++ sdk/python/feast/ui/src/index.tsx | 18 +++---------- sdk/python/feast/ui_server.py | 27 +++++++++---------- 4 files changed, 33 insertions(+), 41 deletions(-) create mode 100644 sdk/python/feast/ui/public/projects-list.json diff --git a/sdk/python/feast/ui/README.md b/sdk/python/feast/ui/README.md index ea5243ca4c..0c11dcf134 100644 --- a/sdk/python/feast/ui/README.md +++ b/sdk/python/feast/ui/README.md @@ -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: @@ -11,23 +11,15 @@ import "@feast-dev/feast-ui/dist/feast-ui.css"; ReactDOM.render( - { - return res.json(); - }) - }} - /> + , 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. diff --git a/sdk/python/feast/ui/public/projects-list.json b/sdk/python/feast/ui/public/projects-list.json new file mode 100644 index 0000000000..b6e79bda5b --- /dev/null +++ b/sdk/python/feast/ui/public/projects-list.json @@ -0,0 +1,11 @@ +{ + "projects": [ + { + "name": "Project", + "description": "Test project", + "id": "project_id", + "registryPath": "http://0.0.0.0:8888/registry" + } + ] + } + \ No newline at end of file diff --git a/sdk/python/feast/ui/src/index.tsx b/sdk/python/feast/ui/src/index.tsx index 4191de17a0..9ddacc9b48 100644 --- a/sdk/python/feast/ui/src/index.tsx +++ b/sdk/python/feast/ui/src/index.tsx @@ -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( - { - return res.json(); - }) - }} - /> + , document.getElementById("root") -); \ No newline at end of file +); diff --git a/sdk/python/feast/ui_server.py b/sdk/python/feast/ui_server.py index cc546f5371..5206dd5161 100644 --- a/sdk/python/feast/ui_server.py +++ b/sdk/python/feast/ui_server.py @@ -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( @@ -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"]) @@ -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)