Skip to content

Commit 6d29572

Browse files
enryHsayalaruano
andauthored
🚧 start to explore adding subsections to homesection (#125)
* 🚧 start to explore adding subsections to homesection * ✨ revert to homepage layout as before, add new section - use the homepage layout as it was before: title, descrpiton, logo and graphical abstract - if there are components in the main folder, trigger to add section with main folder name if the configuration is built using the directory based method. - a new section with the components is added - if configs are created manually, the first section is treated as every other section * 🐛 fix syntax error (two closing parantheses) * 🐛 Make excel df paths relative insetad of absolute * 🚧 add current state of qmd notebooks - move html report file to correct place: update rel. paths - add others as of now * 🐛 ignore description.md and empty sections - do not use description as component in main folder - the description is added to the key description * 🐛 resolve file path first * 🐛 fix issue with non-directory generated config files, add test - do not treat first section special - add example of how to run this config - check in cdci workflow * 🐛 fix path to tests/report_examples * 🐛 add correct file ending.. * ✅ test all report types based on quarto (update static path setting) * 🐛 bash for loop needs to be close using done * 🐛 get rid of absolute path (missed in #136) - update tests - make altair plot path relative to qmd file * 🎨 clean-up comments/prints and improve logic * 📝 Update example config files for basic and EMP case studies and update execution section of README * 💚 Correct paths relative to the docs folder to pass CI tests * 📝 Update README with details about running vuegen using the cofig exmaple files * 🐛 commit change to test from svg to png logo --------- Co-authored-by: sayalaruano <[email protected]>
1 parent 0d173fc commit 6d29572

File tree

16 files changed

+2238
-91
lines changed

16 files changed

+2238
-91
lines changed

.github/workflows/cdci.yml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ jobs:
109109
cd docs
110110
vuegen -dir example_data/Earth_microbiome_vuegen_demo_notebook -rt jupyter
111111
vuegen -c example_data/Earth_microbiome_vuegen_demo_notebook/Earth_microbiome_vuegen_demo_notebook_config.yaml -rt jupyter
112+
- name: quarto html report based on predefined config file
113+
run: |
114+
cd docs
115+
vuegen -c example_config_files/Basic_example_vuegen_demo_notebook_config.yaml -output_dir ../tests/report_examples/Basic_example_vuegen_demo_notebook_cfg/html -rt html
116+
# Check for changes
117+
if git diff ../tests/report_examples | grep .; then
118+
echo "Error: One or more protected files have been modified."
119+
exit 1
120+
fi
112121
- name: check for changes in report files
113122
run: |
114123
# write streamlit report to test folder
@@ -118,7 +127,18 @@ jobs:
118127
echo "Error: One or more protected files have been modified."
119128
exit 1
120129
fi
121-
130+
- name: check for changes in quarto report files
131+
run: |
132+
# write quarto based report to test folder
133+
for format in html pdf docx odt revealjs pptx jupyter; do
134+
vuegen -dir docs/example_data/Basic_example_vuegen_demo_notebook -output_dir tests/report_examples/Basic_example_vuegen_demo_notebook/$format -rt $format
135+
# Check for changes
136+
if git diff tests/report_examples | grep .; then
137+
echo Failed for report: $format
138+
echo "Error: One or more protected files have been modified."
139+
exit 1
140+
fi
141+
done
122142
123143
publish:
124144
name: Publish package to PyPI

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ vuegen --directory docs/example_data/Earth_microbiome_vuegen_demo_notebook --rep
126126

127127
> [!NOTE]
128128
> By default, the `streamlit_autorun` argument is set to False, but you can use it in case you want to automatically run the streamlit app.
129+
> You can also specify the output directory with the `--output_directory` argumument, which defaults to the current working directory.
130+
> See all available arguments with the `--help` option.
131+
129132

130133
### Folder structure
131134

@@ -154,6 +157,8 @@ report_folder/
154157
The titles for sections, subsections, and components are extracted from the corresponding folder and file names, and afterward, users can add descriptions, captions, and other details to the configuration file. Component types are inferred from the file extensions and names.
155158
The order of sections, subsections, and components can be defined using numerical suffixes in folder and file names.
156159

160+
### Configuration file
161+
157162
It's also possible to provide a configuration file instead of a directory:
158163

159164
```bash
@@ -162,6 +167,8 @@ vuegen --config docs/example_config_files/Earth_microbiome_vuegen_demo_notebook.
162167

163168
If a configuration file is given, users can specify titles and descriptions for sections and subsections, as well as component paths and required attributes, such as file format and delimiter for dataframes, plot types, and other details.
164169

170+
The component paths in the configuration file can be absolute or relative to the execution directory. In the examples, we assume that the working directory is the `docs` folder, so the paths are relative to it. If you run VueGen from another directory, you need to adjust the paths accordingly.
171+
165172
The current report types supported by VueGen are:
166173

167174
- Streamlit

docs/example_config_files/Basic_example_vuegen_demo_notebook_config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
report:
22
title: Basic Example Vuegen Demo Notebook
33
description: A general description of the report.
4-
graphical_abstract: https://raw.githubusercontent.com/Multiomics-Analytics-Group/vuegen/main/docs/images/vuegen_logo.svg
5-
logo: https://raw.githubusercontent.com/Multiomics-Analytics-Group/vuegen/main/docs/images/vuegen_logo.svg
4+
graphical_abstract: https://raw.githubusercontent.com/Multiomics-Analytics-Group/vuegen/main/docs/images/vuegen_logo.png
5+
logo: https://raw.githubusercontent.com/Multiomics-Analytics-Group/vuegen/main/docs/images/vuegen_logo.png
66
sections:
77
- title: Plots
88
description: This section contains example plots.

docs/example_config_files/Earth_microbiome_vuegen_demo_notebook_config.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,7 @@ sections:
123123
component_type: PLOT
124124
plot_type: STATIC
125125
- title: Shanon entropy analysis
126-
description: This subsection contains the Shannon entropy analysis of the EMP
127-
dataset.
126+
description: This subsection contains the Shannon entropy analysis of the EMP dataset.
128127
components:
129128
- title: Specificity of sequences and higher taxonomic groups for environment
130129
file_path: https://raw.githubusercontent.com/biocore/emp/master/methods/images/figure4_entropy.png

src/vuegen/config_manager.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ def create_yamlconfig_fromdir(
316316
# Generate the YAML config
317317
yaml_config = {
318318
"report": {
319+
# This will be used for the home section of a report
319320
"title": self._create_title_fromdir(base_dir_path.name),
320321
"description": self._read_description_file(base_dir_path),
321322
"graphical_abstract": "",
@@ -328,11 +329,10 @@ def create_yamlconfig_fromdir(
328329
sorted_sections = self._sort_paths_by_numprefix(list(base_dir_path.iterdir()))
329330

330331
main_section_config = {
331-
"title": "",
332-
"description": "Components added to homepage.",
332+
"title": self._create_title_fromdir(base_dir_path.name),
333+
"description": "",
333334
"components": [],
334335
}
335-
yaml_config["sections"].append(main_section_config)
336336

337337
# Generate sections and subsections config
338338
for section_dir in sorted_sections:
@@ -343,12 +343,20 @@ def create_yamlconfig_fromdir(
343343
# could be single plots?
344344
else:
345345
file_in_main_section_dir = section_dir
346+
if file_in_main_section_dir.name.lower() == "description.md":
347+
continue # Skip description files in the main section
346348
component_config = self._create_component_config_fromfile(
347349
file_in_main_section_dir
348350
)
349351
if component_config is not None:
350352
main_section_config["components"].append(component_config)
351353

354+
if main_section_config["components"]:
355+
# If components were added to the main section, i.e. there were components
356+
# found in the main report directory, add it to the first position of the
357+
# list of sections
358+
yaml_config["sections"].insert(0, main_section_config)
359+
352360
return yaml_config, base_dir_path
353361

354362
def initialize_report(self, config: dict) -> tuple[r.Report, dict]:

src/vuegen/quarto_reportview.py

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def generate_report(self, output_dir: Optional[Path] = None) -> None:
8585
Will overwrite value set on initialization of QuartoReportView.
8686
"""
8787
if output_dir is not None:
88-
self.output_dir = Path(output_dir).resolve().absolute()
88+
self.output_dir = Path(output_dir).resolve()
8989

9090
self.report.logger.debug(
9191
f"Generating '{self.report_type}' report in directory: '{self.output_dir}'"
@@ -130,35 +130,10 @@ def generate_report(self, output_dir: Optional[Path] = None) -> None:
130130
qmd_content.append(
131131
self._generate_image_content(self.report.graphical_abstract)
132132
)
133-
# ? Do we need to handle overview separately?
134-
main_section = self.report.sections[0]
135-
136-
# ! description can be a Markdown component, but it is treated differently
137-
# ! It won't be added to the section content.
138-
if main_section.components:
139-
self.report.logger.debug(
140-
"Adding components of main section folder to the report as overall overview."
141-
)
142-
section_content, section_imports = self._combine_components(
143-
main_section.components
144-
)
145-
if section_content:
146-
qmd_content.append("# General Overview")
147-
148-
if is_report_revealjs:
149-
# Add tabset for revealjs
150-
section_content = [
151-
"::: {.panel-tabset}\n",
152-
*section_content,
153-
":::",
154-
]
155-
qmd_content.extend(section_content)
156-
157-
report_imports.extend(section_imports)
158133

159134
# Add the sections and subsections to the report
160135
self.report.logger.info("Starting to generate sections for the report.")
161-
for section in self.report.sections[1:]:
136+
for section in self.report.sections:
162137
self.report.logger.debug(
163138
f"Processing section: '{section.title}' - {len(section.subsections)} subsection(s)"
164139
)
@@ -568,7 +543,7 @@ def _generate_plot_content(self, plot) -> List[str]:
568543
# ? should that be in the output folder
569544
static_plot_path = (
570545
Path(self.static_dir) / f"{plot.title.replace(' ', '_')}.png"
571-
).absolute()
546+
).resolve()
572547
self.report.logger.debug(f"Static plot path: {static_plot_path}")
573548
else:
574549
html_plot_file = (
@@ -594,7 +569,7 @@ def _generate_plot_content(self, plot) -> List[str]:
594569
plot_content.append(self._generate_plot_code(plot))
595570
if self.is_report_static:
596571
plot_content.append(
597-
f"""fig_altair.save("{static_plot_path.as_posix()}")\n```\n"""
572+
f"""fig_altair.save("{static_plot_path.relative_to(self.output_dir).as_posix()}")\n```\n"""
598573
)
599574
plot_content.append(self._generate_image_content(static_plot_path))
600575
else:

src/vuegen/streamlit_reportview.py

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,12 @@ def generate_report(self, output_dir: str = SECTIONS_DIR) -> None:
150150
report_manag_content.append("\nsections_pages = {}")
151151

152152
# Generate the home page and update the report manager content
153-
# ! top level files (compontents) are added to the home page
154153
self._generate_home_section(
155154
output_dir=output_dir,
156155
report_manag_content=report_manag_content,
157-
home_section=self.report.sections[0],
158156
)
159157

160-
for section in self.report.sections[1:]: # skip home section components
158+
for section in self.report.sections:
161159
# Create a folder for each section
162160
subsection_page_vars = []
163161
section_name_var = make_valid_identifier(
@@ -354,7 +352,6 @@ def _generate_home_section(
354352
self,
355353
output_dir: str,
356354
report_manag_content: list,
357-
home_section: r.Section,
358355
) -> None:
359356
"""
360357
Generates the homepage for the report and updates the report manager content.
@@ -367,13 +364,7 @@ def _generate_home_section(
367364
A list to store the content that will be written to the report manager file.
368365
"""
369366
self.report.logger.debug("Processing home section.")
370-
all_components = []
371-
subsection_imports = []
372-
if home_section.components:
373-
# some assert on title?
374-
all_components, subsection_imports, _ = self._combine_components(
375-
home_section.components
376-
)
367+
377368
try:
378369
# Create folder for the home page
379370
home_dir_path = Path(output_dir) / "Home"
@@ -386,11 +377,7 @@ def _generate_home_section(
386377

387378
# Create the home page content
388379
home_content = []
389-
subsection_imports.append("import streamlit as st")
390-
subsection_imports = set(subsection_imports)
391-
subsection_imports, _ = sort_imports(subsection_imports)
392-
393-
home_content.extend(subsection_imports)
380+
home_content.append("import streamlit as st")
394381
if self.report.description:
395382
home_content.append(
396383
self._format_text(text=self.report.description, type="paragraph")
@@ -401,8 +388,6 @@ def _generate_home_section(
401388
)
402389

403390
# add components content to page (if any)
404-
if all_components:
405-
home_content.extend(all_components)
406391

407392
# Define the footer variable and add it to the home page content
408393
home_content.append("footer = '''" + generate_footer() + "'''\n")
@@ -434,13 +419,11 @@ def _generate_sections(self, output_dir: str) -> None:
434419
The folder where section files will be saved.
435420
"""
436421
self.report.logger.info("Starting to generate sections for the report.")
437-
438422
try:
439-
for section in self.report.sections[1:]:
423+
for section in self.report.sections:
440424
self.report.logger.debug(
441425
f"Processing section '{section.id}': '{section.title}' - {len(section.subsections)} subsection(s)"
442426
)
443-
444427
if section.components:
445428
# add an section overview page
446429
section_content, section_imports, _ = self._combine_components(
@@ -456,9 +439,8 @@ def _generate_sections(self, output_dir: str) -> None:
456439
)
457440

458441
if not section.subsections:
459-
self.report.logger.warning(
460-
f"No subsections found in section: '{section.title}'. "
461-
"To show content in the report, add subsections to the section."
442+
self.report.logger.debug(
443+
f"No subsections found in section: '{section.title}'."
462444
)
463445
continue
464446

@@ -631,7 +613,7 @@ def _generate_plot_content(self, plot) -> List[str]:
631613
else:
632614
plot_content.append(
633615
f"""
634-
with open('{Path(html_plot_file).relative_to(Path.cwd())}', 'r') as html_file:
616+
with open('{Path(html_plot_file).resolve().relative_to(Path.cwd())}', 'r') as html_file:
635617
html_content = html_file.read()\n"""
636618
)
637619

0 commit comments

Comments
 (0)