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

Show scaling warning to user and save user preferences to file. #10331

Merged
merged 1 commit into from
Mar 18, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/test_ert_with_flow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,5 @@ jobs:
run: |
pushd test-data/everest/egg/everest/model
uv run everest lint config_flow.yml
uv run everest run config_flow.yml
uv run everest run config_flow.yml --skip-prompt
popd
2 changes: 1 addition & 1 deletion ci/testkomodo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ run_everest_egg_test() {
fi
cat "$CONFIG"

everest run "$CONFIG"
everest run "$CONFIG" --skip-prompt
STATUS=$?
popd

Expand Down
8 changes: 8 additions & 0 deletions src/everest/bin/everest_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from _ert.threading import ErtThread
from ert.config import ErtConfig, QueueSystem
from everest.bin.utils import show_scaled_controls_warning
from everest.config import EverestConfig, ServerConfig
from everest.detached import (
ServerStatus,
Expand Down Expand Up @@ -96,6 +97,11 @@ def _build_args_parser() -> argparse.ArgumentParser:
action="store_true",
help="Display all jobs executed from the forward model",
)
arg_parser.add_argument(
"--skip-prompt",
action="store_true",
help="Flag used to disable user prompts that will stop execution.",
)

return arg_parser

Expand Down Expand Up @@ -141,6 +147,8 @@ async def run_everest(options: argparse.Namespace) -> None:
and any(os.listdir(options.config.simulation_dir))
):
warn_user_that_runpath_is_nonempty()
if not options.skip_prompt:
show_scaled_controls_warning()

try:
output_dir = options.config.output_dir
Expand Down
48 changes: 48 additions & 0 deletions src/everest/bin/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import argparse
import json
import logging
import os
import sys
Expand All @@ -7,6 +8,8 @@
from collections.abc import Sequence
from dataclasses import dataclass, field
from itertools import groupby
from pathlib import Path
from textwrap import dedent
from typing import Any, ClassVar

import colorama
Expand Down Expand Up @@ -375,3 +378,48 @@ def report_on_previous_run(
f" `everest run --new-run {config_file}`\n"
f"Results are stored in {optimization_output_dir}"
)


def _read_user_preferences(user_info_path: Path) -> dict[str, dict[str, Any]]:
try:
if user_info_path.exists():
with open(user_info_path, encoding="utf-8") as f:
return json.load(f)

user_info = {EVEREST: {"show_scaling_warning": True}}
with open(user_info_path, mode="w", encoding="utf-8") as f:
json.dump(user_info, f, ensure_ascii=False, indent=4)
return user_info
except json.decoder.JSONDecodeError:
return {EVEREST: {}}


def show_scaled_controls_warning() -> None:
user_info_path = Path(os.getenv("HOME", "")) / ".ert"
user_info = _read_user_preferences(user_info_path)
everest_pref = user_info.get(EVEREST, {})

if not everest_pref.get("show_scaling_warning", True):
return

user_input = input(
dedent("""
From Everest version: 14.0.3, Everest will output auto-scaled control values.
Control values should now be specified in real-world units instead of the optimizer's internal scale.
The 'scaled_range' property can still be used to configure the optimizer's range for each control.

[Enter] to continue.
[ Y ] to stop showing this message again.
[ N ] to abort.
""")
).lower()
match user_input:
case "y":
everest_pref["show_scaling_warning"] = False
try:
with open(user_info_path, mode="w", encoding="utf-8") as f:
json.dump(user_info, f, ensure_ascii=False, indent=4)
except Exception as e:
logging.getLogger(EVEREST).error(str(e))
case "n":
raise SystemExit(0)
18 changes: 9 additions & 9 deletions tests/everest/entry_points/test_everest_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def test_everest_entry_debug(
):
"""Test running everest with --debug"""
with caplog.at_level(logging.DEBUG):
everest_entry([CONFIG_FILE_MINIMAL, "--debug"])
everest_entry([CONFIG_FILE_MINIMAL, "--debug", "--skip"])
logstream = "\n".join(caplog.messages)
start_server_mock.assert_called_once()
wait_for_server_mock.assert_called_once()
Expand Down Expand Up @@ -79,7 +79,7 @@ def test_everest_entry(
copy_math_func_test_data_to_tmp,
):
"""Test running everest in detached mode"""
everest_entry([CONFIG_FILE_MINIMAL])
everest_entry([CONFIG_FILE_MINIMAL, "--skip"])
start_server_mock.assert_called_once()
wait_for_server_mock.assert_called_once()
start_monitor_mock.assert_called_once()
Expand Down Expand Up @@ -108,7 +108,7 @@ def test_everest_entry_detached_already_run(
"""Test everest detached, when an optimization has already run"""
# optimization already run, notify the user
with capture_streams() as (out, _):
everest_entry([CONFIG_FILE_MINIMAL])
everest_entry([CONFIG_FILE_MINIMAL, "--skip-prompt"])
assert "--new-run" in out.getvalue()
start_server_mock.assert_not_called()
start_monitor_mock.assert_not_called()
Expand All @@ -122,7 +122,7 @@ def test_everest_entry_detached_already_run(
everserver_status_mock.assert_not_called()

# forcefully re-run the case
everest_entry([CONFIG_FILE_MINIMAL, "--new-run"])
everest_entry([CONFIG_FILE_MINIMAL, "--new-run", "--skip-prompt"])
start_server_mock.assert_called_once()
start_monitor_mock.assert_called_once()
everserver_status_mock.assert_called()
Expand Down Expand Up @@ -176,7 +176,7 @@ def test_everest_entry_detached_running(
"""Test everest detached, optimization is running"""
# can't start a new run if one is already running
with capture_streams() as (out, _):
everest_entry([CONFIG_FILE_MINIMAL, "--new-run"])
everest_entry([CONFIG_FILE_MINIMAL, "--new-run", "--skip-prompt"])
assert "everest kill" in out.getvalue()
assert "everest monitor" in out.getvalue()
start_server_mock.assert_not_called()
Expand All @@ -199,7 +199,7 @@ def test_everest_entry_detached_running(
# if already running, nothing happens
assert "everest kill" in out.getvalue()
assert "everest monitor" in out.getvalue()
everest_entry([CONFIG_FILE_MINIMAL])
everest_entry([CONFIG_FILE_MINIMAL, "--skip-prompt"])
start_server_mock.assert_not_called()
server_is_running_mock_everest_script.assert_called_once()
everserver_status_mock.assert_called()
Expand Down Expand Up @@ -293,7 +293,7 @@ def test_exception_raised_when_server_run_fails(
copy_math_func_test_data_to_tmp,
):
with pytest.raises(SystemExit, match="Reality was ripped to shreds!"):
everest_entry([CONFIG_FILE_MINIMAL])
everest_entry([CONFIG_FILE_MINIMAL, "--skip-prompt"])


@patch("everest.bin.monitor_script.server_is_running", return_value=True)
Expand Down Expand Up @@ -326,7 +326,7 @@ def test_complete_status_for_normal_run(
start_monitor_mock,
copy_math_func_test_data_to_tmp,
):
everest_entry([CONFIG_FILE_MINIMAL])
everest_entry([CONFIG_FILE_MINIMAL, "--skip-prompt"])
config = EverestConfig.load_file(CONFIG_FILE_MINIMAL)
status_path = ServerConfig.get_everserver_status_path(config.output_dir)
status = everserver_status(status_path)
Expand Down Expand Up @@ -377,4 +377,4 @@ def test_validate_ert_config_before_starting_everest_server(
everest_config.dump(config_file)

with pytest.raises(SystemExit, match="Config validation error:"):
everest_entry([config_file])
everest_entry([config_file, "--skip-prompt"])
4 changes: 2 additions & 2 deletions tests/everest/functional/test_main_everest_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def test_everest_entry_run(cached_example):
_, config_file, _, _ = cached_example("math_func/config_minimal.yml")
# Setup command line arguments
with capture_streams():
start_everest(["everest", "run", config_file])
start_everest(["everest", "run", config_file, "--skip-prompt"])

config = EverestConfig.load_file(config_file)
status = everserver_status(
Expand Down Expand Up @@ -180,7 +180,7 @@ def wait_and_kill():
thread.start()

with pytest.raises(SystemExit):
start_everest(["everest", "run", CONFIG_FILE_ADVANCED])
start_everest(["everest", "run", CONFIG_FILE_ADVANCED, "--skip-prompt"])

out = capsys.readouterr().out

Expand Down
2 changes: 1 addition & 1 deletion tests/everest/test_everest_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def test_that_multiple_everest_clients_can_connect_to_server(cached_example):

# Run the case through everserver
everest_main_thread = threading.Thread(
target=everest_entry, args=[[str(config_path)]]
target=everest_entry, args=[[str(config_path), "--skip-prompt"]]
)

everest_main_thread.start()
Expand Down
2 changes: 1 addition & 1 deletion tests/everest/test_everest_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def test_save_running_config(_, _1, _2, _3, _4, _5, copy_math_func_test_data_to_
# optimization already run, notify the user
file_name = "config_minimal.yml"
config = EverestConfig.load_file(file_name)
everest_entry([file_name])
everest_entry([file_name, "--skip-prompt"])
saved_config_path = os.path.join(config.output_dir, file_name)

assert os.path.exists(saved_config_path)
Expand Down
2 changes: 1 addition & 1 deletion tests/everest/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def test_logging_setup(copy_math_func_test_data_to_tmp):

# start_server() loads config based on config_path, so we need to actually overwrite it
everest_config.dump("config_minimal.yml")
start_everest(["everest", "run", "config_minimal.yml"])
start_everest(["everest", "run", "config_minimal.yml", "--skip-prompt"])

everest_output_path = os.path.join(os.getcwd(), "everest_output")
everest_logs_dir_path = everest_config.log_dir
Expand Down
Loading