Skip to content

Commit

Permalink
Merge pull request #140 from MichaelPesce/use-env-for-project
Browse files Browse the repository at this point in the history
Use frontend env variable for setting project/brand
  • Loading branch information
MichaelPesce authored Nov 22, 2024
2 parents 0c26c6f + e2c9edb commit cfdbe3c
Show file tree
Hide file tree
Showing 20 changed files with 283 additions and 164 deletions.
19 changes: 11 additions & 8 deletions .github/workflows/electron-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: App build
on:
push:
branches:
- "1.1rc0"
- "build"

defaults:
run:
Expand Down Expand Up @@ -49,16 +49,19 @@ jobs:

- name: Install Watertap locally
working-directory: ../
run: git clone https://github.com/watertap-org/watertap.git && cd watertap && git fetch --all --tags && git checkout 1.1.0 && pip install --progress-bar off .

- name: Transfer Entry points
run: |
npm --prefix electron run move-entrypoints
run: git clone https://github.com/watertap-org/watertap.git && cd watertap && pip install --progress-bar off .

# - name: Install Prommis
# run: pip install --progress-bar off prommis

- name: Install watertap-ui Python package
run: |
pip install --progress-bar off .
- name: Transfer Entry points
run: |
python move_entrypoints.py -p watertap
- name: Build Backend
run: npm --prefix electron run build-backend

Expand All @@ -70,7 +73,7 @@ jobs:

- name: Sign Windows Distribution
run: |
AzureSignTool sign -kvu "${{ secrets.AZURE_KEY_VAULT_URI }}" -kvi "${{ secrets.AZURE_CLIENT_ID }}" -kvt "${{ secrets.AZURE_TENANT_ID }}" -kvs "${{ secrets.AZURE_CLIENT_SECRET }}" -kvc ${{ secrets.AZURE_CERT_NAME }} -tr http://timestamp.digicert.com -v electron/dist/WaterTAP-UI_24.10.11_win64.exe
AzureSignTool sign -kvu "${{ secrets.AZURE_KEY_VAULT_URI }}" -kvi "${{ secrets.AZURE_CLIENT_ID }}" -kvt "${{ secrets.AZURE_TENANT_ID }}" -kvs "${{ secrets.AZURE_CLIENT_SECRET }}" -kvc ${{ secrets.AZURE_CERT_NAME }} -tr http://timestamp.digicert.com -v electron/dist/WaterTAP-UI_24.11.20_win64.exe
- name: Upload artifact for windows build
Expand All @@ -79,4 +82,4 @@ jobs:
with:
name: windows-dist
path: |
electron/dist/WaterTAP-UI_24.10.11_win64.exe
electron/dist/WaterTAP-UI_24.11.20_win64.exe
15 changes: 11 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ jobs:
run: |
echo REACT_APP_THEME=watertap >> .env
- name: Install Electron JS dependencies
run: |
npm --prefix electron clean-install
# - name: Install Electron JS dependencies
# run: |
# npm --prefix electron clean-install

- name: Install frontend JS dependencies
run: |
Expand Down Expand Up @@ -135,7 +135,10 @@ jobs:
- name: Rename conda package cache
if: runner.os == 'Windows'
shell: bash
run: mv "${CONDA_PKGS_DIR}" "${CONDA_PKGS_DIR}_do_not_cache"
run: | # Try renaming hardcoded directory
if [ -d C:\\Users\\runneradmin\\conda_pkgs_dir ]; then
mv C:\\Users\\runneradmin\\conda_pkgs_dir C:\\Users\\runneradmin\\conda_pkgs_dir_do_not_cache
fi
pytest:
name: pytest (${{ matrix.os }})
Expand All @@ -162,6 +165,10 @@ jobs:
activate-environment: watertap-ui-env
miniforge-version: latest

# Set project as environment variable. This can also be set by the frontend.
- name: Set env
run: echo "project=nawi" >> $GITHUB_ENV

- name: Install watertap-ui Python package
run: |
pip install --progress-bar off .
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,5 @@ get-idaes-extensions-dist/
cert/
extensions/
setup-extensions-dist/
sweep_outputs/
sweep_outputs/
math.nist.gov/
32 changes: 27 additions & 5 deletions backend/app/internal/flowsheet_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import tinydb # JSON single-file 'database'

# package-local
from app.internal.settings import AppSettings
from app.internal.settings import Deployment, AppSettings
from watertap.ui.fsapi import FlowsheetInterface
import idaes.logger as idaeslog

Expand Down Expand Up @@ -73,12 +73,28 @@ def __init__(self, **kwargs):
Args:
**kwargs: Passed as keywords to :class:`AppSettings`.
"""
self.app_settings = AppSettings(**kwargs)
self._objs, self._flowsheets = {}, {}
current_project = os.environ.get("project", None)
if current_project:
self.set_project(current_project)
self.startup_time = time.time()


def set_project(self, project: str):
os.environ["project"] = project
self._objs, self._flowsheets = {}, {}
self.project = project
self._dpy = Deployment(project)

# Set App Settings
self.app_settings = AppSettings(
packages = list(self._dpy.package),
log_dir = self._dpy.data_basedir / "logs",
custom_flowsheets_dir = self._dpy.data_basedir / "custom_flowsheets",
data_basedir = self._dpy.data_basedir,
)

# Add custom flowsheets path to the system path
self.custom_flowsheets_path = self.app_settings.data_basedir / "custom_flowsheets"
self.custom_flowsheets_path = self.app_settings.custom_flowsheets_dir
sys.path.append(str(self.custom_flowsheets_path))

for package in self.app_settings.packages:
Expand All @@ -98,6 +114,10 @@ def __init__(self, **kwargs):
path = self.app_settings.data_basedir / self.HISTORY_DB_FILE
self._histdb = tinydb.TinyDB(path)

## set last run
self.set_last_run_dictionary()

def set_last_run_dictionary(self):
# check for (and set if necessary) the last_run dictionary
query = tinydb.Query()
last_run_dict = self._histdb.search(
Expand Down Expand Up @@ -570,6 +590,8 @@ def add_custom_flowsheets(self):
try:
_log.info(f"adding imported flowsheet module: {f}")
module_name = f.replace(".py", "")
if module_name in sys.modules:
sys.modules.pop(module_name)
custom_module = importlib.import_module(module_name)
fsi = self._get_flowsheet_interface(custom_module)
self.add_flowsheet_interface(module_name, fsi, custom=True)
Expand Down Expand Up @@ -613,7 +635,7 @@ def set_number_of_subprocesses(self, value):

def get_logs_path(self):
"""Return logs path."""
return self.app_settings.log_dir / "nawi-ui_backend_logs.log"
return self.app_settings.log_dir / "ui_backend_logs.log"

@staticmethod
def _get_flowsheet_interface(module: ModuleType) -> Optional[FlowsheetInterface]:
Expand Down
45 changes: 17 additions & 28 deletions backend/app/internal/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os
from pathlib import Path
import logging
from logging import handlers as logging_handlers
from typing import List, Union
from pydantic import field_validator
from pydantic_settings import BaseSettings
Expand All @@ -17,7 +18,6 @@
_log.addHandler(h)
_log.setLevel(logging.WARNING)


class Deployment:
"""Values related to the deployment context of the UI,
e.g., NAWI WaterTAP, PROMMIS, or IDAES.
Expand All @@ -32,13 +32,7 @@ class Deployment:
}
DEFAULT_PROJ = "nawi"

def __init__(self):
try:
project = os.environ[self.PROJECT_ENV].lower()
except KeyError:
project = self.DEFAULT_PROJ
_log.warning(f"Project name not found in environment variable '{self.PROJECT_ENV}',"
f"using default")
def __init__(self, project=DEFAULT_PROJ):
_log.info(f"Deploy for project={project}")
if project not in self.PROJ.keys():
valid_projects = ", ".join((str(x) for x in self.PROJ))
Expand All @@ -53,31 +47,24 @@ def __init__(self):
raise
_log.info(f"Deployment: project={self.project} package={self.package} data_basedir={self.data_basedir}")


_dpy = Deployment()


class AppSettings(BaseSettings):
#: List of package names in which to look for flowsheets
packages: List[str] = list(_dpy.package)
log_dir: Union[Path, None] = None
custom_flowsheets_dir: Union[Path, None] = None
data_basedir: Path = _dpy.data_basedir
packages: List[str]
log_dir: Path
custom_flowsheets_dir: Path
data_basedir : Path

# @validator("log_dir", always=True)
@field_validator("log_dir")
def validate_log_dir(cls, v):
if v is None:
v = _dpy.data_basedir / "logs"
_log.info(f"Creating log directory '{v}'")
v.mkdir(parents=True, exist_ok=True)

logging_format = "[%(levelname)s] %(asctime)s %(name)s " \
"(%(filename)s:%(lineno)s): %(message)s"
project_log_file = f"{_dpy.project}-ui_backend_logs.log"
project_log_file = f"ui_backend_logs.log"
_log.info(f"Logs will be in rotating files with base name "
f"'{v/project_log_file}'")
logging_file_handler = logging.handlers.RotatingFileHandler(
f"'{v/project_log_file}'")
logging_file_handler = logging_handlers.RotatingFileHandler(
v / project_log_file,
backupCount=2,
maxBytes=5000000,
Expand All @@ -90,14 +77,16 @@ def validate_log_dir(cls, v):
# @validator("custom_flowsheets_dir", always=True)
@field_validator("custom_flowsheets_dir")
def validate_custom_flowsheets_dir(cls, v):
if v is None:
v = _dpy.data_basedir / "custom_flowsheets"
v.mkdir(parents=True, exist_ok=True)
return v

class Config:
env_prefix = f"{_dpy.project.upper()}_"
# class Config:
# env_prefix = f"{_dpy.project.upper()}_"


# def get_deployment() -> Deployment:
# return _dpy

def get_deployment() -> Deployment:
return _dpy
# def set_deployment(project_name) -> Deployment:
# _dpy = Deployment(project_name)
# return _dpy
1 change: 1 addition & 0 deletions backend/app/main-hooks/hook-watertap.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

# add all modules to watertap modules hidden imports

# for package in ["watertap", "pyomo", "scipy", "prommis"]:
for package in ["watertap", "pyomo", "scipy"]:
pkg = importlib.import_module(package)
try:
Expand Down
27 changes: 18 additions & 9 deletions backend/app/routers/flowsheets.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from app.internal.flowsheet_manager import FlowsheetManager, FlowsheetInfo
from app.internal.parameter_sweep import run_parameter_sweep
from app.internal.log_parser import parse_logs
from app.internal.settings import get_deployment
from watertap.ui.fsapi import FlowsheetInterface, FlowsheetExport
import idaes.logger as idaeslog

Expand Down Expand Up @@ -524,15 +523,15 @@ async def get_logs() -> List:
return parse_logs(logs_path, flowsheet_manager.startup_time)


@router.get("/project")
async def get_project_name() -> str:
"""Get Project name.
# @router.get("/project")
# async def get_project_name() -> str:
# """Get Project name.

Returns:
Name of the project
"""
dpy = get_deployment()
return dpy.project
# Returns:
# Name of the project
# """
# dpy = get_deployment()
# return dpy.project


@router.post("/download_logs", response_class=FileResponse)
Expand All @@ -544,3 +543,13 @@ async def download_logs() -> Path:
"""
logs_path = flowsheet_manager.get_logs_path()
return logs_path

@router.get("/set_project/{project_name}")
async def set_project(project_name: str) -> str:
"""Set Project in settings.
Returns:
Name of the project
"""
flowsheet_manager.set_project(project_name)
return project_name
15 changes: 8 additions & 7 deletions backend/tests/app/internal/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,28 @@
def test_deployment_valid_projects():
# use approved project names
for p in Deployment.PROJ:
os.environ[Deployment.PROJECT_ENV] = p
d = Deployment()
d = Deployment(p)
assert d.project == p


def test_deployment_invalid_projects():
# try bad project names
for name in "bad", "", "\U0001f600":
os.environ[Deployment.PROJECT_ENV] = name
with pytest.raises(ValueError):
_ = Deployment()
_ = Deployment(name)


def test_deployment_env_default():
# unset the env entirely
del os.environ[Deployment.PROJECT_ENV]
dpy = Deployment()
assert dpy.project == Deployment.DEFAULT_PROJ

def test_appsettings():
settings = AppSettings()
settings = AppSettings(
packages = ["watertap"],
log_dir = "./nawi/logs",
custom_flowsheets_dir = "./nawi/custom_flowsheets",
data_basedir = "./nawi/",
)
assert settings.packages
assert settings.log_dir
assert settings.custom_flowsheets_dir
Expand Down
4 changes: 2 additions & 2 deletions electron/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions electron/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "watertap-ui",
"author": "Michael Pesce <[email protected]>",
"version": "24.10.11",
"version": "24.11.20",
"private": true,
"main": "build/main.js",
"dependencies": {
Expand Down Expand Up @@ -71,7 +71,7 @@
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true,
"artifactName": "WaterTAP-UI_24.10.11_win64.exe"
"artifactName": "WaterTAP-UI_24.11.20_win64.exe"
},
"deb": {
"depends": [
Expand Down Expand Up @@ -107,7 +107,7 @@
"win": {
"target": "nsis",
"icon": "build/nawi-logo.ico",
"artifactName": "WaterTAP-UI_24.10.11_win64.exe"
"artifactName": "WaterTAP-UI_24.11.20_win64.exe"
},
"linux": {
"target": "Deb",
Expand Down
Loading

0 comments on commit cfdbe3c

Please sign in to comment.