Skip to content
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
45 changes: 27 additions & 18 deletions apparun/gui/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

class Module(BaseModel):
name: Optional[str] = None
tab: Optional[str] = None
lca_data_path: Optional[str] = None
impact_model_path: Optional[str] = None
input_panel: Optional[InputPanel] = None
Expand Down Expand Up @@ -105,6 +106,7 @@ def run(self):
class GUI(BaseModel):
name: Optional[str] = None
favicon_path: Optional[str] = None
tabs: Optional[List[str]] = None
modules: List[Module]

def setup_layout(self):
Expand All @@ -127,18 +129,7 @@ def setup_layout(self):
"""
)

def gen_titles_modules(self):
if self.name is not None:
self.modules.insert(
0,
Module(
**{
"output_panels": [
{"type": "markdown", "message": f"# {self.name}"}
]
}
),
)
def gen_titles_modules(self, tabs):
modules_with_titles = []
for module in self.modules:
if module.name is None:
Expand All @@ -149,16 +140,34 @@ def gen_titles_modules(self):
**{
"output_panels": [
{"type": "markdown", "message": f"## {module.name}"}
]
],
"tab": module.tab,
}
)
)
modules_with_titles.append(module)
self.modules = modules_with_titles

def run(self):
self.gen_titles_modules()
containers = [st.container() for i in range(len(self.modules))]
for i in range(len(self.modules)):
with containers[i]:
self.modules[i].run()
if self.name is not None:
Module(
**{"output_panels": [{"type": "markdown", "message": f"# {self.name}"}]}
).run()
self.gen_titles_modules(self.tabs)
if self.tabs is not None:
tabs = st.tabs(self.tabs)
for i in range(len(self.tabs)):
tab_name = self.tabs[i]
with tabs[i]:
tab_modules = [
module for module in self.modules if module.tab == tab_name
]
containers = [tabs[i].container() for _ in range(len(tab_modules))]
for j in range(len(tab_modules)):
with containers[j]:
tab_modules[j].run()
else:
containers = [st.container() for i in range(len(self.modules))]
for i in range(len(self.modules)):
with containers[i]:
self.modules[i].run()
65 changes: 65 additions & 0 deletions samples/conf/multi_tab_sample_gui.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: "Preconfigured tool for NVIDIA AI GPU"
favicon_path: "https://www.cea.fr/PublishingImages/cea.jpg"
tabs:
- "1st tab"
- "2nd tab"
modules:
- impact_model_path: "samples/impact_models/nvidia_ai_gpu_chip.yaml"
name: "Scenario comparison by phase"
tab: "1st tab"
input_panel:
type: input_scenario_form_panel
name: "GPU parameters"
fields:
- type: float
name: cuda_core
min: 0
max: 1024
default: 512
- type: enum
name: architecture
options:
- Pascal
- Maxwell
- type: float
name: lifespan
min: 0
max: 5
default: 2
- type: enum
name: usage_location
options:
- FR
- EU
output_panels:
- type: scenario_comparison_dynamic_output_panel
y: EFV3_CLIMATE_CHANGE
hue: phase
by_property: "phase"
- name: "Random explanation"
tab: "1st tab"
output_panels:
- type: markdown
message: "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
- impact_model_path: "samples/impact_models/nvidia_ai_gpu_chip.yaml"
name: "Test"
tab: "2nd tab"
input_panel:
type: input_scenario_form_panel
name: "Still GPU parameters but less"
fields:
- type: float
name: cuda_core
min: 0
max: 1024
default: 512
- type: enum
name: architecture
options:
- Pascal
- Maxwell
default: Pascal
output_panels:
- type: scenario_comparison_dynamic_output_panel
y: EFV3_CLIMATE_CHANGE
hue: component
16 changes: 16 additions & 0 deletions tests/data/conf/functional_multi_tab_gui.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: "Preconfigured tool for NVIDIA AI GPU"
favicon_path: "https://www.cea.fr/PublishingImages/cea.jpg"
tabs:
- "1st tab"
- "2nd tab"
modules:
- name: "Random explanation"
tab: "1st tab"
output_panels:
- type: markdown
message: "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
- name: "Random explanation"
tab: "2nd tab"
output_panels:
- type: markdown
message: "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
20 changes: 20 additions & 0 deletions tests/end_to_end/test_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ def run_test_gui():
generate_gui("tests/data/conf/functional_gui.yaml")


def run_multi_tab_test_gui():
from apparun.cli.main import generate_gui

generate_gui("tests/data/conf/functional_multi_tab_gui.yaml")


def test_streamlit_app_is_deploying():
"""
Check that the streamlit app initialized by sample conf is deploying.
Expand All @@ -27,6 +33,20 @@ def test_streamlit_app_is_deploying():
assert len(at.markdown) == 3


def test_multi_tab_streamlit_app_is_deploying():
"""
Check that the streamlit app initialized by sample conf is deploying.
"""

at = AppTest.from_function(run_multi_tab_test_gui, default_timeout=10)
at.run()
# five md widgets: one title, plus one header and one text block per tab.
assert len(at.tabs) == 2
assert len(at.tabs[0]) == 2
assert len(at.tabs[1]) == 2
assert len(at.markdown) == 5


def test_favicons():
"""
Check that local and remote favicon can be loaded.
Expand Down
Loading