diff --git a/.github/workflows/cdci.yml b/.github/workflows/cdci.yml
index 22a06df..fd1f553 100644
--- a/.github/workflows/cdci.yml
+++ b/.github/workflows/cdci.yml
@@ -20,8 +20,12 @@ jobs:
- uses: actions/checkout@v4
- uses: psf/black@stable
with:
- jupyter: true
+ # ! for now (format output files of vuegen for streamlit)
+ src: "./src"
- uses: isort/isort-action@v1
+ with:
+ # ! should be removed once all imports are correctly sorted
+ sort-paths: src
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
@@ -67,6 +71,7 @@ jobs:
run: |
cd docs
vuegen -dir example_data/Earth_microbiome_vuegen_demo_notebook
+ # here we are testing that the generated config from the -dir call works
vuegen -c example_data/Earth_microbiome_vuegen_demo_notebook/Earth_microbiome_vuegen_demo_notebook_config.yaml
# repeat for easier inspection on GitHub:
- name: quarto html report
@@ -104,6 +109,16 @@ jobs:
cd docs
vuegen -dir example_data/Earth_microbiome_vuegen_demo_notebook -rt jupyter
vuegen -c example_data/Earth_microbiome_vuegen_demo_notebook/Earth_microbiome_vuegen_demo_notebook_config.yaml -rt jupyter
+ - name: check for changes in report files
+ run: |
+ # write streamlit report to test folder
+ vuegen -dir docs/example_data/Basic_example_vuegen_demo_notebook -output_dir tests/report_examples/Basic_example_vuegen_demo_notebook
+ # Check for changes
+ if git diff tests/report_examples | grep .; then
+ echo "Error: One or more protected files have been modified."
+ exit 1
+ fi
+
publish:
name: Publish package to PyPI
diff --git a/.gitignore b/.gitignore
index 6c57dc2..dafea3c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -116,7 +116,8 @@ cython_debug/
# Temporary files
logs/
vuegen/logs/
-streamlit_report/
+./streamlit_report/
+!tests/report_examples
quarto_report/
output_docker/
@@ -129,4 +130,4 @@ docs/images/Graphical_abstract/
docs/images/Nfcore_module_figure
docs/presentations/
basic_example_vuegen_demo_notebook_config.yaml
-earth_microbiome_vuegen_demo_notebook_config.yaml
\ No newline at end of file
+earth_microbiome_vuegen_demo_notebook_config.yaml
diff --git a/src/vuegen/streamlit_reportview.py b/src/vuegen/streamlit_reportview.py
index 8ed3a8e..69ce63a 100644
--- a/src/vuegen/streamlit_reportview.py
+++ b/src/vuegen/streamlit_reportview.py
@@ -9,7 +9,13 @@
from . import report as r
from . import table_utils
-from .utils import create_folder, generate_footer, get_relative_file_path, is_url
+from .utils import (
+ create_folder,
+ generate_footer,
+ get_relative_file_path,
+ is_url,
+ sort_imports,
+)
from .utils.variables import make_valid_identifier
@@ -368,7 +374,6 @@ def _generate_home_section(
all_components, subsection_imports, _ = self._combine_components(
home_section.components
)
-
try:
# Create folder for the home page
home_dir_path = Path(output_dir) / "Home"
@@ -381,9 +386,11 @@ def _generate_home_section(
# Create the home page content
home_content = []
- home_content.append("import streamlit as st")
- if subsection_imports:
- home_content.extend(subsection_imports)
+ subsection_imports.append("import streamlit as st")
+ subsection_imports = set(subsection_imports)
+ subsection_imports, _ = sort_imports(subsection_imports)
+
+ home_content.extend(subsection_imports)
if self.report.description:
home_content.append(
self._format_text(text=self.report.description, type="paragraph")
@@ -517,6 +524,8 @@ def _combine_components(self, components: list[dict]) -> tuple[list, list, bool]
all_contents.extend(content)
# remove duplicates
all_imports = list(set(all_imports))
+ all_imports, setup_statements = sort_imports(all_imports)
+ all_imports.extend(setup_statements)
return all_contents, all_imports, has_chatbot
def _generate_subsection(self, subsection) -> tuple[List[str], List[str]]:
diff --git a/tests/report_examples/.gitignore b/tests/report_examples/.gitignore
new file mode 100644
index 0000000..2d19fc7
--- /dev/null
+++ b/tests/report_examples/.gitignore
@@ -0,0 +1 @@
+*.html
diff --git a/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Dataframes/All_Formats.py b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Dataframes/All_Formats.py
new file mode 100644
index 0000000..a26eb0a
--- /dev/null
+++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Dataframes/All_Formats.py
@@ -0,0 +1,146 @@
+from st_aggrid import AgGrid, GridOptionsBuilder
+from vuegen import table_utils
+import pandas as pd
+import streamlit as st
+df_index = 1
+
+st.markdown('''
All Formats
''', unsafe_allow_html=True)
+st.markdown('''Phyla Correlation Network Csv
''', unsafe_allow_html=True)
+df = pd.read_csv('docs/example_data/Basic_example_vuegen_demo_notebook/2_Dataframes/1_All_formats/1_phyla_correlation_network_csv.csv')
+
+
+# Displays a DataFrame using AgGrid with configurable options.
+grid_builder = GridOptionsBuilder.from_dataframe(df)
+grid_builder.configure_default_column(editable=True, groupable=True, filter=True)
+grid_builder.configure_side_bar(filters_panel=True, columns_panel=True)
+grid_builder.configure_selection(selection_mode="multiple")
+grid_builder.configure_pagination(enabled=True, paginationAutoPageSize=False, paginationPageSize=20)
+grid_options = grid_builder.build()
+
+AgGrid(df, gridOptions=grid_options, enable_enterprise_modules=True)
+
+# Button to download the df
+df_csv = df.to_csv(sep=',', header=True, index=False).encode('utf-8')
+st.download_button(
+ label="Download dataframe as CSV",
+ data=df_csv,
+ file_name=f"dataframe_{df_index}.csv",
+ mime='text/csv',
+ key=f"download_button_{df_index}")
+df_index += 1
+st.markdown('''Abundance Table Example Xls
''', unsafe_allow_html=True)
+selected_sheet = 0
+sheet_names = table_utils.get_sheet_names("/home/runner/work/vuegen/vuegen/docs/example_data/Basic_example_vuegen_demo_notebook/2_Dataframes/1_All_formats/2_abundance_table_example_xls.xls")
+selected_sheet = st.selectbox("Select a sheet to display", options=sheet_names)
+
+df = pd.read_excel('/home/runner/work/vuegen/vuegen/docs/example_data/Basic_example_vuegen_demo_notebook/2_Dataframes/1_All_formats/2_abundance_table_example_xls.xls', sheet_name=selected_sheet)
+
+
+# Displays a DataFrame using AgGrid with configurable options.
+grid_builder = GridOptionsBuilder.from_dataframe(df)
+grid_builder.configure_default_column(editable=True, groupable=True, filter=True)
+grid_builder.configure_side_bar(filters_panel=True, columns_panel=True)
+grid_builder.configure_selection(selection_mode="multiple")
+grid_builder.configure_pagination(enabled=True, paginationAutoPageSize=False, paginationPageSize=20)
+grid_options = grid_builder.build()
+
+AgGrid(df, gridOptions=grid_options, enable_enterprise_modules=True)
+
+# Button to download the df
+df_csv = df.to_csv(sep=',', header=True, index=False).encode('utf-8')
+st.download_button(
+ label="Download dataframe as CSV",
+ data=df_csv,
+ file_name=f"dataframe_{df_index}.csv",
+ mime='text/csv',
+ key=f"download_button_{df_index}")
+df_index += 1
+st.markdown('''Sample Info Example Txt
''', unsafe_allow_html=True)
+df = pd.read_table('docs/example_data/Basic_example_vuegen_demo_notebook/2_Dataframes/1_All_formats/3_sample_info_example_txt.txt')
+
+
+# Displays a DataFrame using AgGrid with configurable options.
+grid_builder = GridOptionsBuilder.from_dataframe(df)
+grid_builder.configure_default_column(editable=True, groupable=True, filter=True)
+grid_builder.configure_side_bar(filters_panel=True, columns_panel=True)
+grid_builder.configure_selection(selection_mode="multiple")
+grid_builder.configure_pagination(enabled=True, paginationAutoPageSize=False, paginationPageSize=20)
+grid_options = grid_builder.build()
+
+AgGrid(df, gridOptions=grid_options, enable_enterprise_modules=True)
+
+# Button to download the df
+df_csv = df.to_csv(sep=',', header=True, index=False).encode('utf-8')
+st.download_button(
+ label="Download dataframe as CSV",
+ data=df_csv,
+ file_name=f"dataframe_{df_index}.csv",
+ mime='text/csv',
+ key=f"download_button_{df_index}")
+df_index += 1
+st.markdown('''Sample Info Example Parquet
''', unsafe_allow_html=True)
+df = pd.read_parquet('docs/example_data/Basic_example_vuegen_demo_notebook/2_Dataframes/1_All_formats/4_sample_info_example_parquet.parquet')
+
+
+# Displays a DataFrame using AgGrid with configurable options.
+grid_builder = GridOptionsBuilder.from_dataframe(df)
+grid_builder.configure_default_column(editable=True, groupable=True, filter=True)
+grid_builder.configure_side_bar(filters_panel=True, columns_panel=True)
+grid_builder.configure_selection(selection_mode="multiple")
+grid_builder.configure_pagination(enabled=True, paginationAutoPageSize=False, paginationPageSize=20)
+grid_options = grid_builder.build()
+
+AgGrid(df, gridOptions=grid_options, enable_enterprise_modules=True)
+
+# Button to download the df
+df_csv = df.to_csv(sep=',', header=True, index=False).encode('utf-8')
+st.download_button(
+ label="Download dataframe as CSV",
+ data=df_csv,
+ file_name=f"dataframe_{df_index}.csv",
+ mime='text/csv',
+ key=f"download_button_{df_index}")
+df_index += 1
+st.markdown('''Example Xlsx
''', unsafe_allow_html=True)
+selected_sheet = 0
+df = pd.read_excel('/home/runner/work/vuegen/vuegen/docs/example_data/Basic_example_vuegen_demo_notebook/2_Dataframes/1_All_formats/5_example_xlsx.xlsx', sheet_name=selected_sheet)
+
+
+# Displays a DataFrame using AgGrid with configurable options.
+grid_builder = GridOptionsBuilder.from_dataframe(df)
+grid_builder.configure_default_column(editable=True, groupable=True, filter=True)
+grid_builder.configure_side_bar(filters_panel=True, columns_panel=True)
+grid_builder.configure_selection(selection_mode="multiple")
+grid_builder.configure_pagination(enabled=True, paginationAutoPageSize=False, paginationPageSize=20)
+grid_options = grid_builder.build()
+
+AgGrid(df, gridOptions=grid_options, enable_enterprise_modules=True)
+
+# Button to download the df
+df_csv = df.to_csv(sep=',', header=True, index=False).encode('utf-8')
+st.download_button(
+ label="Download dataframe as CSV",
+ data=df_csv,
+ file_name=f"dataframe_{df_index}.csv",
+ mime='text/csv',
+ key=f"download_button_{df_index}")
+df_index += 1
+footer = '''
+'''
+
+st.markdown(footer, unsafe_allow_html=True)
diff --git a/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Home/Homepage.py b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Home/Homepage.py
new file mode 100644
index 0000000..cfdf5d6
--- /dev/null
+++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Home/Homepage.py
@@ -0,0 +1,30 @@
+import requests
+import streamlit as st
+st.markdown('''A general description of the report.
+
''', unsafe_allow_html=True)
+st.markdown('''Description
''', unsafe_allow_html=True)
+
+with open('docs/example_data/Basic_example_vuegen_demo_notebook/description.md', 'r') as markdown_file:
+ markdown_content = markdown_file.read()
+
+st.markdown(markdown_content, unsafe_allow_html=True)
+
+footer = '''
+'''
+
+st.markdown(footer, unsafe_allow_html=True)
diff --git a/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Html/All_Html.py b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Html/All_Html.py
new file mode 100644
index 0000000..18c444a
--- /dev/null
+++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Html/All_Html.py
@@ -0,0 +1,52 @@
+import requests
+import streamlit as st
+
+st.markdown('''All Html
''', unsafe_allow_html=True)
+st.markdown('''Plot
''', unsafe_allow_html=True)
+
+with open('docs/example_data/Basic_example_vuegen_demo_notebook/4_Html/1_All_html/1_plot.html', 'r', encoding='utf-8') as html_file:
+ html_content = html_file.read()
+
+st.components.v1.html(html_content, height=600, scrolling=True)
+
+st.markdown('''Ckg Network
''', unsafe_allow_html=True)
+
+with open('docs/example_data/Basic_example_vuegen_demo_notebook/4_Html/1_All_html/2_ckg_network.html', 'r') as html_file:
+ html_content = html_file.read()
+
+
+st.markdown(f" Number of nodes: 33
", unsafe_allow_html=True)
+st.markdown(f" Number of relationships: 35
", unsafe_allow_html=True)
+
+# Streamlit checkbox for controlling the layout
+control_layout = st.checkbox('Add panel to control layout', value=True)
+net_html_height = 1200 if control_layout else 630
+# Load HTML into HTML component for display on Streamlit
+st.components.v1.html(html_content, height=net_html_height)
+
+st.markdown('''Multiqc Report
''', unsafe_allow_html=True)
+
+with open('docs/example_data/Basic_example_vuegen_demo_notebook/4_Html/1_All_html/3_multiqc_report.html', 'r', encoding='utf-8') as html_file:
+ html_content = html_file.read()
+
+st.components.v1.html(html_content, height=600, scrolling=True)
+
+footer = '''
+'''
+
+st.markdown(footer, unsafe_allow_html=True)
diff --git a/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Markdown/All_Markdown.py b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Markdown/All_Markdown.py
new file mode 100644
index 0000000..b866236
--- /dev/null
+++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Markdown/All_Markdown.py
@@ -0,0 +1,30 @@
+import requests
+import streamlit as st
+
+st.markdown('''All Markdown
''', unsafe_allow_html=True)
+st.markdown('''Readme
''', unsafe_allow_html=True)
+
+with open('docs/example_data/Basic_example_vuegen_demo_notebook/5_Markdown/1_All_markdown/README.md', 'r') as markdown_file:
+ markdown_content = markdown_file.read()
+
+st.markdown(markdown_content, unsafe_allow_html=True)
+
+footer = '''
+'''
+
+st.markdown(footer, unsafe_allow_html=True)
diff --git a/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Networks/Interactive_Networks.py b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Networks/Interactive_Networks.py
new file mode 100644
index 0000000..02f146e
--- /dev/null
+++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Networks/Interactive_Networks.py
@@ -0,0 +1,47 @@
+import requests
+import streamlit as st
+
+st.markdown('''Interactive Networks
''', unsafe_allow_html=True)
+st.markdown('''Optional description for subsection.
+
''', unsafe_allow_html=True)
+st.markdown('''Man Example
''', unsafe_allow_html=True)
+
+with open('tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/static/Man_Example.html', 'r') as html_file:
+ html_content = html_file.read()
+
+
+st.markdown(f" Number of nodes: 9
", unsafe_allow_html=True)
+st.markdown(f" Number of relationships: 14
", unsafe_allow_html=True)
+
+# Streamlit checkbox for controlling the layout
+control_layout = st.checkbox('Add panel to control layout', value=True)
+net_html_height = 1200 if control_layout else 630
+# Load HTML into HTML component for display on Streamlit
+st.components.v1.html(html_content, height=net_html_height)
+
+st.markdown('''Description
''', unsafe_allow_html=True)
+
+with open('docs/example_data/Basic_example_vuegen_demo_notebook/3_Networks/1_Interactive_networks/description.md', 'r') as markdown_file:
+ markdown_content = markdown_file.read()
+
+st.markdown(markdown_content, unsafe_allow_html=True)
+
+footer = '''
+'''
+
+st.markdown(footer, unsafe_allow_html=True)
diff --git a/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Networks/Static_Networks.py b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Networks/Static_Networks.py
new file mode 100644
index 0000000..59a2b7b
--- /dev/null
+++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Networks/Static_Networks.py
@@ -0,0 +1,26 @@
+import streamlit as st
+
+st.markdown('''Static Networks
''', unsafe_allow_html=True)
+st.markdown('''Phyla Correlation Network
''', unsafe_allow_html=True)
+
+st.image('docs/example_data/Basic_example_vuegen_demo_notebook/3_Networks/2_Static_networks/1_phyla_correlation_network.png', caption='', use_column_width=True)
+
+footer = '''
+'''
+
+st.markdown(footer, unsafe_allow_html=True)
diff --git a/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Plots/Interactive_Plots.py b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Plots/Interactive_Plots.py
new file mode 100644
index 0000000..8084d36
--- /dev/null
+++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Plots/Interactive_Plots.py
@@ -0,0 +1,98 @@
+import altair as alt
+import json
+import requests
+import streamlit as st
+
+st.markdown('''Interactive Plots
''', unsafe_allow_html=True)
+st.markdown('''Optional description for section.
+
''', unsafe_allow_html=True)
+st.markdown('''Top Species Plot By Biome Plotly
''', unsafe_allow_html=True)
+
+with open('docs/example_data/Basic_example_vuegen_demo_notebook/1_Plots/1_Interactive_plots/1_top_species_plot_by_biome_plotly.json', 'r') as plot_file:
+ plot_json = json.load(plot_file)
+
+# Keep only 'data' and 'layout' sections
+plot_json = {key: plot_json[key] for key in plot_json if key in ['data', 'layout']}
+
+# Remove 'frame' section in 'data'
+plot_json['data'] = [{k: v for k, v in entry.items() if k != 'frame'} for entry in plot_json.get('data', [])]
+st.plotly_chart(plot_json, use_container_width=True)
+
+st.markdown('''Multiline Plot Altair
''', unsafe_allow_html=True)
+
+with open('docs/example_data/Basic_example_vuegen_demo_notebook/1_Plots/1_Interactive_plots/2_multiline_plot_altair.json', 'r') as plot_file:
+ plot_json = json.load(plot_file)
+
+altair_plot = alt.Chart.from_dict(plot_json)
+st.vega_lite_chart(json.loads(altair_plot.to_json()), use_container_width=True)
+
+st.markdown('''Pie Plot Countries Plotly
''', unsafe_allow_html=True)
+
+with open('docs/example_data/Basic_example_vuegen_demo_notebook/1_Plots/1_Interactive_plots/3_pie_plot_countries_plotly.json', 'r') as plot_file:
+ plot_json = json.load(plot_file)
+
+# Keep only 'data' and 'layout' sections
+plot_json = {key: plot_json[key] for key in plot_json if key in ['data', 'layout']}
+
+# Remove 'frame' section in 'data'
+plot_json['data'] = [{k: v for k, v in entry.items() if k != 'frame'} for entry in plot_json.get('data', [])]
+st.plotly_chart(plot_json, use_container_width=True)
+
+st.markdown('''Pie Plots Biomes Plotly
''', unsafe_allow_html=True)
+
+with open('docs/example_data/Basic_example_vuegen_demo_notebook/1_Plots/1_Interactive_plots/4_pie_plots_biomes_plotly.json', 'r') as plot_file:
+ plot_json = json.load(plot_file)
+
+# Keep only 'data' and 'layout' sections
+plot_json = {key: plot_json[key] for key in plot_json if key in ['data', 'layout']}
+
+# Remove 'frame' section in 'data'
+plot_json['data'] = [{k: v for k, v in entry.items() if k != 'frame'} for entry in plot_json.get('data', [])]
+st.plotly_chart(plot_json, use_container_width=True)
+
+st.markdown('''Saline Metagenomics Samples Map Altair
''', unsafe_allow_html=True)
+
+with open('docs/example_data/Basic_example_vuegen_demo_notebook/1_Plots/1_Interactive_plots/5_saline_metagenomics_samples_map_altair.json', 'r') as plot_file:
+ plot_json = json.load(plot_file)
+
+altair_plot = alt.Chart.from_dict(plot_json)
+st.vega_lite_chart(json.loads(altair_plot.to_json()), use_container_width=True)
+
+st.markdown('''Plotly Plot R
''', unsafe_allow_html=True)
+
+with open('docs/example_data/Basic_example_vuegen_demo_notebook/1_Plots/1_Interactive_plots/6_plotly_plot_R.json', 'r') as plot_file:
+ plot_json = json.load(plot_file)
+
+# Keep only 'data' and 'layout' sections
+plot_json = {key: plot_json[key] for key in plot_json if key in ['data', 'layout']}
+
+# Remove 'frame' section in 'data'
+plot_json['data'] = [{k: v for k, v in entry.items() if k != 'frame'} for entry in plot_json.get('data', [])]
+st.plotly_chart(plot_json, use_container_width=True)
+
+st.markdown('''Description
''', unsafe_allow_html=True)
+
+with open('docs/example_data/Basic_example_vuegen_demo_notebook/1_Plots/1_Interactive_plots/description.md', 'r') as markdown_file:
+ markdown_content = markdown_file.read()
+
+st.markdown(markdown_content, unsafe_allow_html=True)
+
+footer = '''
+'''
+
+st.markdown(footer, unsafe_allow_html=True)
diff --git a/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Plots/Static_Plots.py b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Plots/Static_Plots.py
new file mode 100644
index 0000000..c88666c
--- /dev/null
+++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Plots/Static_Plots.py
@@ -0,0 +1,34 @@
+import streamlit as st
+
+st.markdown('''Static Plots
''', unsafe_allow_html=True)
+st.markdown('''Number Samples Per Study
''', unsafe_allow_html=True)
+
+st.image('docs/example_data/Basic_example_vuegen_demo_notebook/1_Plots/2_Static_plots/1_number_samples_per_study.png', caption='', use_column_width=True)
+
+st.markdown('''Animal Metagenomics Samples Map
''', unsafe_allow_html=True)
+
+st.image('docs/example_data/Basic_example_vuegen_demo_notebook/1_Plots/2_Static_plots/2_animal_metagenomics_samples_map.png', caption='', use_column_width=True)
+
+st.markdown('''Alpha Diversity Host Associated Samples
''', unsafe_allow_html=True)
+
+st.image('docs/example_data/Basic_example_vuegen_demo_notebook/1_Plots/2_Static_plots/3_alpha_diversity_host_associated_samples.png', caption='', use_column_width=True)
+
+footer = '''
+'''
+
+st.markdown(footer, unsafe_allow_html=True)
diff --git a/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/report_manager.py b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/report_manager.py
new file mode 100644
index 0000000..78edc2d
--- /dev/null
+++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/report_manager.py
@@ -0,0 +1,45 @@
+import os
+import time
+
+import psutil
+import streamlit as st
+
+st.set_page_config(layout="wide", page_title="Basic Example Vuegen Demo Notebook")
+
+st.markdown('''Basic Example Vuegen Demo Notebook
''', unsafe_allow_html=True)
+
+sections_pages = {}
+homepage = st.Page('Home/Homepage.py', title='Homepage')
+sections_pages['Home'] = [homepage]
+
+Interactive_Plots = st.Page('Plots/Interactive_Plots.py', title='Interactive Plots')
+Static_Plots = st.Page('Plots/Static_Plots.py', title='Static Plots')
+sections_pages['Plots'] = [Interactive_Plots, Static_Plots]
+
+All_Formats = st.Page('Dataframes/All_Formats.py', title='All Formats')
+sections_pages['Dataframes'] = [All_Formats]
+
+Interactive_Networks = st.Page('Networks/Interactive_Networks.py', title='Interactive Networks')
+Static_Networks = st.Page('Networks/Static_Networks.py', title='Static Networks')
+sections_pages['Networks'] = [Interactive_Networks, Static_Networks]
+
+All_Html = st.Page('Html/All_Html.py', title='All Html')
+sections_pages['Html'] = [All_Html]
+
+All_Markdown = st.Page('Markdown/All_Markdown.py', title='All Markdown')
+sections_pages['Markdown'] = [All_Markdown]
+
+report_nav = st.navigation(sections_pages)
+
+# Following https://discuss.streamlit.io/t/close-streamlit-app-with-button-click/35132/5
+exit_app = st.sidebar.button("Shut Down App", icon=":material/power_off:", use_container_width=True)
+if exit_app:
+ st.toast("Shutting down the app...")
+ time.sleep(1)
+ # Terminate streamlit python process
+ pid = os.getpid()
+ p = psutil.Process(pid)
+ p.terminate()
+
+
+report_nav.run()
diff --git a/tests/report_examples/README.md b/tests/report_examples/README.md
new file mode 100644
index 0000000..188c28f
--- /dev/null
+++ b/tests/report_examples/README.md
@@ -0,0 +1,13 @@
+# Report files as examples and for testing
+
+- the files are used to check for changes in
+ the 'CICD Python Package' Action (`cdci.yaml`)
+- if there are differences observed, the Action will fail, although the report can
+ still be the same which is generated based on the streamlit Python files or `.qmd` files
+- if changes are intended, one needs to commit the changnes to this folder
+
+```bash
+# main folder of the repository
+
+vuegen -dir docs/example_data/Basic_example_vuegen_demo_notebook -output_dir tests/report_examples/Basic_example_vuegen_demo_notebook
+```