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

ECS-6433 heuristic loading #231 #348

Merged
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d8ba42c
Updated cli.py so 'happi load' can handle glob searches, like 'happi …
janeliu-slac Oct 9, 2024
6450a1e
Added pre-commit changes.
janeliu-slac Oct 9, 2024
779086d
Updated cli.py with logic to handle user input with glob and non-glob…
janeliu-slac Oct 10, 2024
06274c5
Updated cli.py with documentation for the new feature and pre-commit …
janeliu-slac Oct 10, 2024
9cfbf0c
Added release notes.
janeliu-slac Oct 10, 2024
85a13c0
Removed the line "if '*' not in (' '.join(search_criteria))".
janeliu-slac Oct 10, 2024
137bb18
Recoded the feature to gather the results of each search term individ…
janeliu-slac Oct 11, 2024
37d9c06
Removed some print statements used for testing.
janeliu-slac Oct 11, 2024
7b25139
Updated cli.py so 'happi load' can handle glob searches, like 'happi …
janeliu-slac Oct 9, 2024
ef16b22
Added pre-commit changes.
janeliu-slac Oct 9, 2024
87013ad
Updated cli.py with logic to handle user input with glob and non-glob…
janeliu-slac Oct 10, 2024
8386902
Updated cli.py with documentation for the new feature and pre-commit …
janeliu-slac Oct 10, 2024
4f4982a
Added release notes.
janeliu-slac Oct 10, 2024
5e86159
Removed the line "if '*' not in (' '.join(search_criteria))".
janeliu-slac Oct 10, 2024
987daed
Recoded the feature to gather the results of each search term individ…
janeliu-slac Oct 11, 2024
c7ca35f
Removed some print statements used for testing.
janeliu-slac Oct 11, 2024
aa3fa70
Merge remote-tracking branch 'refs/remotes/origin/ECS-6433_heuristic_…
janeliu-slac Oct 15, 2024
997f39c
In cli.py load() function removed 'term' and replaced with '[item]' f…
janeliu-slac Oct 16, 2024
226a012
Tried to pass name values from SearchResult objects obtained from cli…
janeliu-slac Oct 16, 2024
d2c5ff3
Updated test_load_glob_args() function with names of mock devices in …
janeliu-slac Oct 18, 2024
39777ff
Added a second glob parameter to test_load_glob_args() in test_cli.py.
janeliu-slac Oct 18, 2024
733be20
Created a second unit test for the happi load() function to handle mu…
janeliu-slac Oct 18, 2024
0fa9f5e
Added release notes.
janeliu-slac Oct 19, 2024
a790d08
Delete docs/source/upcoming_release_notes/348-heuristic_loading.rst
janeliu-slac Oct 19, 2024
3d2cc7a
Updated release notes.
janeliu-slac Oct 19, 2024
fd38612
Updated release notes.
janeliu-slac Oct 21, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
348 ECS-6433 heuristic loading
#################

API Breaks
----------
- N/A

Features
--------
- Updated happi's ``load()`` function to support searching and loading in one user-friendly expression. The load function gathers the results of each search term individually and loads the union of the results.

Bugfixes
--------
- N/A

Maintenance
-----------
- Cleaned up code by removing stray ``print()`` statements.
- Added unit tests for the new feature.
- In the load function of cli.py removed ``term=[]`` and replaced with ``[item]`` for readability.

Contributors
------------
- janeliu-slac
32 changes: 27 additions & 5 deletions happi/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,21 +396,43 @@ def edit(ctx, name: str, edits: list[str]):


@happi_cli.command()
@click.argument('item_names', nargs=-1)
@click.option('--glob/--regex', 'use_glob', default=True,
help='use glob style (default) or regex style search terms. '
r'Regex requires backslashes to be escaped (eg. at\\d.\\d)')
@click.argument('search_criteria', nargs=-1)
@click.pass_context
def load(ctx, item_names: list[str]):
"""Open IPython terminal with ITEM_NAMES loaded."""
def load(
ctx: click.Context,
use_glob: bool,
search_criteria: list[str]
):
results = set()

for item in search_criteria:
final_results = search_parser(
client=get_happi_client_from_config(ctx.obj),
use_glob=use_glob,
search_criteria=[item],
)
if not final_results:
print('%s was not found.' % item)
else:
for res in final_results:
results.add(res['name'])

# Open IPython terminal with RESULTS loaded

logger.debug('Starting load block')
# retrieve client
client = get_happi_client_from_config(ctx.obj)

devices = {}
names = " ".join(item_names)
names = " ".join(results)
names = names.split()

if len(names) < 1:
raise click.BadArgumentUsage('No item names given')
logger.info(f'Creating shell with devices {item_names}')
logger.info(f'Creating shell with devices {results}')

for name in names:
try:
Expand Down
74 changes: 69 additions & 5 deletions happi/tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ def assert_match_expected(
"""
logger.debug(result.output)
assert result.exit_code == expected_return
assert not result.exception or (isinstance(result.exception, SystemExit)
and expected_return != 0)
assert not result.exception or (isinstance(result.exception, SystemExit) and
expected_return != 0)

trimmed_output = trim_split_output(result.output)
for message, expected in zip(trimmed_output, expected_output):
Expand All @@ -91,7 +91,8 @@ def assert_in_expected(
"""
logger.debug(result.output)
assert result.exit_code == expected_return
assert not result.exception or (isinstance(result.exception, SystemExit) and expected_return != 0)
assert not result.exception or (isinstance(
result.exception, SystemExit) and expected_return != 0)
assert expected_inclusion in result.output


Expand Down Expand Up @@ -579,7 +580,7 @@ def test_bad_edit(edit_args: list[str], happi_cfg: str, runner: CliRunner):
assert bad_edit_result.exit_code == 1


def test_load(
def test_load_one_arg(
caplog: pytest.LogCaptureFixture,
client: happi.client.Client,
happi_cfg: str,
Expand Down Expand Up @@ -616,6 +617,69 @@ def test_load(
assert "Creating shell with devices" in caplog.text


def test_load_multiple_args(
caplog: pytest.LogCaptureFixture,
client: happi.client.Client,
happi_cfg: str,
runner: CliRunner
):
# try to load the item
devices = {}
devices['tst_base_pim'] = client.load_device(name='tst_base_pim')
devices['tst_base_pim2'] = client.load_device(name='tst_base_pim2')
with mock.patch.object(IPython, 'start_ipython') as m:
_ = runner.invoke(
happi_cli, ['--path', happi_cfg, 'load', 'tst_base_pim', 'tst_base_pim2']
)
m.assert_called_once_with(argv=['--quick'], user_ns=devices)
with caplog.at_level(logging.INFO):
assert "Creating shell with devices" in caplog.text


def test_load_glob_one_arg(
caplog: pytest.LogCaptureFixture,
client: happi.client.Client,
happi_cfg: str,
runner: CliRunner
):
# try to load the item
devices = {}
devices['tst_base_pim'] = client.load_device(name='tst_base_pim')
devices['tst_base_pim2'] = client.load_device(name='tst_base_pim2')
devices['tst_minimal'] = client.load_device(name='tst_minimal')

with mock.patch.object(IPython, 'start_ipython') as m:
_ = runner.invoke(
happi_cli, ['--path', happi_cfg, 'load', 'tst_*']
)
m.assert_called_once_with(argv=['--quick'], user_ns=devices)

with caplog.at_level(logging.INFO):
assert "Creating shell with devices" in caplog.text


def test_load_glob_multiple_args(
caplog: pytest.LogCaptureFixture,
client: happi.client.Client,
happi_cfg: str,
runner: CliRunner
):
# try to load the item
devices = {}
devices['tst_base_pim'] = client.load_device(name='tst_base_pim')
devices['tst_base_pim2'] = client.load_device(name='tst_base_pim2')
devices['tst_minimal'] = client.load_device(name='tst_minimal')

with mock.patch.object(IPython, 'start_ipython') as m:
_ = runner.invoke(
happi_cli, ['--path', happi_cfg, 'load', 'tst_*', 'device_class=types*']
janeliu-slac marked this conversation as resolved.
Show resolved Hide resolved
)
m.assert_called_once_with(argv=['--quick'], user_ns=devices)

with caplog.at_level(logging.INFO):
assert "Creating shell with devices" in caplog.text


@pytest.mark.parametrize("wrapper", ['{{ "tst_base_pim2":{} }}', "[{}]"])
def test_update(wrapper: str, happi_cfg: str, runner: CliRunner):
new = """{
Expand Down Expand Up @@ -789,7 +853,7 @@ def arg_variants(variants: tuple[tuple[tuple[str]]]):
"""
for idx, arg_set in enumerate(itertools.product(*variants), 1):
item = functools.reduce(
lambda x, y: x+y,
lambda x, y: x + y,
arg_set,
)
summary = f"args{idx}_" + ",".join(item)
Expand Down