From ddf195f54d693876c9bb2aba80fff7759812f1d9 Mon Sep 17 00:00:00 2001 From: Henry Webel Date: Fri, 20 Jun 2025 10:25:13 +0200 Subject: [PATCH 01/13] :sparkles: add current main state of streamlit report Python files --- .../sections/Dataframes/All_Formats.py | 146 ++++++++++++++++++ .../sections/Home/Homepage.py | 31 ++++ .../sections/Html/All_Html.py | 52 +++++++ .../sections/Markdown/All_Markdown.py | 30 ++++ .../sections/Networks/Interactive_Networks.py | 47 ++++++ .../sections/Networks/Static_Networks.py | 26 ++++ .../sections/Plots/Interactive_Plots.py | 98 ++++++++++++ .../sections/Plots/Static_Plots.py | 34 ++++ .../sections/report_manager.py | 45 ++++++ tests/report_examples/README.md | 13 ++ 10 files changed, 522 insertions(+) create mode 100644 tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Dataframes/All_Formats.py create mode 100644 tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Home/Homepage.py create mode 100644 tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Html/All_Html.py create mode 100644 tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Markdown/All_Markdown.py create mode 100644 tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Networks/Interactive_Networks.py create mode 100644 tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Networks/Static_Networks.py create mode 100644 tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Plots/Interactive_Plots.py create mode 100644 tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Plots/Static_Plots.py create mode 100644 tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/report_manager.py create mode 100644 tests/report_examples/README.md 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..cd006b4 --- /dev/null +++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Dataframes/All_Formats.py @@ -0,0 +1,146 @@ +import pandas as pd +import streamlit as st +df_index = 1 +from vuegen import table_utils +from st_aggrid import AgGrid, GridOptionsBuilder + +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("/Users/heweb/Documents/repos/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('/Users/heweb/Documents/repos/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('/Users/heweb/Documents/repos/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..09a6243 --- /dev/null +++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Home/Homepage.py @@ -0,0 +1,31 @@ +import streamlit as st +import streamlit as st +import requests +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..47f06b2 --- /dev/null +++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Html/All_Html.py @@ -0,0 +1,52 @@ +import streamlit as st +import requests + +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..ccd38f3 --- /dev/null +++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Markdown/All_Markdown.py @@ -0,0 +1,30 @@ +import streamlit as st +import requests + +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..ad74415 --- /dev/null +++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Networks/Interactive_Networks.py @@ -0,0 +1,47 @@ +import streamlit as st +import requests + +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..6229eec --- /dev/null +++ b/tests/report_examples/Basic_example_vuegen_demo_notebook/streamlit_report/sections/Plots/Interactive_Plots.py @@ -0,0 +1,98 @@ +import json +import streamlit as st +import requests +import altair as alt + +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 +``` From 2dd9c420bc9fc86b145d5533f69cd62e27c76e9d Mon Sep 17 00:00:00 2001 From: Henry Webel Date: Fri, 20 Jun 2025 10:26:32 +0200 Subject: [PATCH 02/13] =?UTF-8?q?=F0=9F=99=88=20hide=20unformatted=20html?= =?UTF-8?q?=20files=20for=20now=20(could=20use=20prettier=20etc=20before?= =?UTF-8?q?=20writing=20to=20file)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/report_examples/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/report_examples/.gitignore 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 From 9a6a08034aa9f0016ab78aca213f4ded8be7b98b Mon Sep 17 00:00:00 2001 From: Henry Webel Date: Fri, 20 Jun 2025 10:41:15 +0200 Subject: [PATCH 03/13] :sparkles: use git diff to detect changes (should not fail atm) --- .github/workflows/cdci.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/cdci.yml b/.github/workflows/cdci.yml index 22a06df..d0a0f6c 100644 --- a/.github/workflows/cdci.yml +++ b/.github/workflows/cdci.yml @@ -104,6 +104,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 From 1f827998377ec7da865d1015b8687a53596f08cb Mon Sep 17 00:00:00 2001 From: Henry Webel Date: Fri, 20 Jun 2025 11:11:19 +0200 Subject: [PATCH 04/13] :art: sort for now only src and docs folder --- .github/workflows/cdci.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cdci.yml b/.github/workflows/cdci.yml index d0a0f6c..02795cc 100644 --- a/.github/workflows/cdci.yml +++ b/.github/workflows/cdci.yml @@ -19,9 +19,12 @@ jobs: steps: - uses: actions/checkout@v4 - uses: psf/black@stable - with: - jupyter: true - uses: isort/isort-action@v1 + with: + # ! should be removed once all imports are correctly sorted + sort-paths: | + src + another_folder - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: @@ -67,6 +70,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 From f7f670c9e677cbdc525aa1e4e27fb98cdcbc4132 Mon Sep 17 00:00:00 2001 From: Henry Webel Date: Fri, 20 Jun 2025 12:24:21 +0200 Subject: [PATCH 05/13] :bug: only one folder supported translated to run `isort --check-only --diff src` --- .github/workflows/cdci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/cdci.yml b/.github/workflows/cdci.yml index 02795cc..3a5bfa8 100644 --- a/.github/workflows/cdci.yml +++ b/.github/workflows/cdci.yml @@ -22,9 +22,7 @@ jobs: - uses: isort/isort-action@v1 with: # ! should be removed once all imports are correctly sorted - sort-paths: | - src - another_folder + sort-paths: src - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: From e0e3754268b50ce20828402e37c70eae639fbe88 Mon Sep 17 00:00:00 2001 From: Henry Webel Date: Fri, 20 Jun 2025 12:31:19 +0200 Subject: [PATCH 06/13] :bug: fix import in home section ( no duplication and sorted) --- src/vuegen/streamlit_reportview.py | 17 +++++++++++++---- .../streamlit_report/sections/Home/Homepage.py | 3 +-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/vuegen/streamlit_reportview.py b/src/vuegen/streamlit_reportview.py index 8ed3a8e..d1da058 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 @@ -381,9 +387,12 @@ 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") 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 index 09a6243..cfdf5d6 100644 --- 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 @@ -1,6 +1,5 @@ -import streamlit as st -import streamlit as st 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) From b0dce90a12b46e127d5394b9e7d2c8ced246c4b7 Mon Sep 17 00:00:00 2001 From: Henry Webel Date: Fri, 20 Jun 2025 12:43:37 +0200 Subject: [PATCH 07/13] :bug: sort imports so it's not depend on random (set), statements after imports --- src/vuegen/streamlit_reportview.py | 4 ++-- .../streamlit_report/sections/Dataframes/All_Formats.py | 4 ++-- .../streamlit_report/sections/Html/All_Html.py | 2 +- .../streamlit_report/sections/Markdown/All_Markdown.py | 2 +- .../sections/Networks/Interactive_Networks.py | 2 +- .../streamlit_report/sections/Plots/Interactive_Plots.py | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/vuegen/streamlit_reportview.py b/src/vuegen/streamlit_reportview.py index d1da058..69ce63a 100644 --- a/src/vuegen/streamlit_reportview.py +++ b/src/vuegen/streamlit_reportview.py @@ -374,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" @@ -388,7 +387,6 @@ def _generate_home_section( # Create the home page content home_content = [] subsection_imports.append("import streamlit as st") - subsection_imports = set(subsection_imports) subsection_imports, _ = sort_imports(subsection_imports) @@ -526,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/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 index cd006b4..3107f7a 100644 --- 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 @@ -1,8 +1,8 @@ +from st_aggrid import AgGrid, GridOptionsBuilder +from vuegen import table_utils import pandas as pd import streamlit as st df_index = 1 -from vuegen import table_utils -from st_aggrid import AgGrid, GridOptionsBuilder st.markdown('''

All Formats

''', unsafe_allow_html=True) st.markdown('''

Phyla Correlation Network Csv

''', 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 index 47f06b2..18c444a 100644 --- 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 @@ -1,5 +1,5 @@ -import streamlit as st import requests +import streamlit as st st.markdown('''

All Html

''', unsafe_allow_html=True) st.markdown('''

Plot

''', 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 index ccd38f3..b866236 100644 --- 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 @@ -1,5 +1,5 @@ -import streamlit as st import requests +import streamlit as st st.markdown('''

All Markdown

''', unsafe_allow_html=True) st.markdown('''

Readme

''', 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 index ad74415..02f146e 100644 --- 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 @@ -1,5 +1,5 @@ -import streamlit as st import requests +import streamlit as st st.markdown('''

Interactive Networks

''', unsafe_allow_html=True) st.markdown('''

Optional description for subsection. 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 index 6229eec..8084d36 100644 --- 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 @@ -1,7 +1,7 @@ +import altair as alt import json -import streamlit as st import requests -import altair as alt +import streamlit as st st.markdown('''

Interactive Plots

''', unsafe_allow_html=True) st.markdown('''

Optional description for section. From bc92bda7062f56439f08b703899307819de79a95 Mon Sep 17 00:00:00 2001 From: Henry Webel Date: Fri, 20 Jun 2025 12:44:33 +0200 Subject: [PATCH 08/13] =?UTF-8?q?=F0=9F=99=88=20show=20changes=20to=20stre?= =?UTF-8?q?amlit=20folders=20unter=20tests/report=5Fexamples?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6c57dc2..dcb46fd 100644 --- a/.gitignore +++ b/.gitignore @@ -117,6 +117,7 @@ cython_debug/ logs/ vuegen/logs/ 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 From 9bb0dfa853bf502c4b420d0321151f41efd6344e Mon Sep 17 00:00:00 2001 From: Henry Webel Date: Fri, 20 Jun 2025 12:58:49 +0200 Subject: [PATCH 09/13] :bug: some paths are not yet relative... --- .../streamlit_report/sections/Dataframes/All_Formats.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 index 3107f7a..6af8b7c 100644 --- 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 @@ -30,10 +30,10 @@ df_index += 1 st.markdown('''

Abundance Table Example Xls

''', unsafe_allow_html=True) selected_sheet = 0 -sheet_names = table_utils.get_sheet_names("/Users/heweb/Documents/repos/vuegen/docs/example_data/Basic_example_vuegen_demo_notebook/2_Dataframes/1_All_formats/2_abundance_table_example_xls.xls") +sheet_names = table_utils.get_sheet_names("/home/runner/work/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('/Users/heweb/Documents/repos/vuegen/docs/example_data/Basic_example_vuegen_demo_notebook/2_Dataframes/1_All_formats/2_abundance_table_example_xls.xls', sheet_name=selected_sheet) +df = pd.read_excel('/home/runner/work/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. @@ -103,7 +103,7 @@ df_index += 1 st.markdown('''

Example Xlsx

''', unsafe_allow_html=True) selected_sheet = 0 -df = pd.read_excel('/Users/heweb/Documents/repos/vuegen/docs/example_data/Basic_example_vuegen_demo_notebook/2_Dataframes/1_All_formats/5_example_xlsx.xlsx', sheet_name=selected_sheet) +df = pd.read_excel('/home/runner/work/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. From 20fc7df6c43c0bde071d6e68bbb78607ee50c241 Mon Sep 17 00:00:00 2001 From: Henry Webel Date: Fri, 20 Jun 2025 13:21:21 +0200 Subject: [PATCH 10/13] :art: do not format tests folder for now --- .github/workflows/cdci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/cdci.yml b/.github/workflows/cdci.yml index 3a5bfa8..fd1f553 100644 --- a/.github/workflows/cdci.yml +++ b/.github/workflows/cdci.yml @@ -19,6 +19,9 @@ jobs: steps: - uses: actions/checkout@v4 - uses: psf/black@stable + with: + # ! 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 From e371f0266cbaa8363dbba2dc26a023d640bdeb86 Mon Sep 17 00:00:00 2001 From: Henry Webel Date: Fri, 20 Jun 2025 13:43:02 +0200 Subject: [PATCH 11/13] :bug: fix path (which is still absolute) --- .gitignore | 2 +- .../streamlit_report/sections/Dataframes/All_Formats.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index dcb46fd..dafea3c 100644 --- a/.gitignore +++ b/.gitignore @@ -116,7 +116,7 @@ cython_debug/ # Temporary files logs/ vuegen/logs/ -streamlit_report/ +./streamlit_report/ !tests/report_examples quarto_report/ output_docker/ 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 index 6af8b7c..a26eb0a 100644 --- 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 @@ -30,10 +30,10 @@ 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/docs/example_data/Basic_example_vuegen_demo_notebook/2_Dataframes/1_All_formats/2_abundance_table_example_xls.xls") +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/docs/example_data/Basic_example_vuegen_demo_notebook/2_Dataframes/1_All_formats/2_abundance_table_example_xls.xls', sheet_name=selected_sheet) +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. @@ -103,7 +103,7 @@ df_index += 1 st.markdown('''

Example Xlsx

''', unsafe_allow_html=True) selected_sheet = 0 -df = pd.read_excel('/home/runner/work/vuegen/docs/example_data/Basic_example_vuegen_demo_notebook/2_Dataframes/1_All_formats/5_example_xlsx.xlsx', sheet_name=selected_sheet) +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. From 44746f30017f5e6723a7d5990a6bfdbcfc7c359a Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Fri, 20 Jun 2025 16:12:48 +0200 Subject: [PATCH 12/13] =?UTF-8?q?=F0=9F=90=9B=20Correct=20relative=20paths?= =?UTF-8?q?=20for=20excel=20dataframes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuegen/streamlit_reportview.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vuegen/streamlit_reportview.py b/src/vuegen/streamlit_reportview.py index 69ce63a..22da703 100644 --- a/src/vuegen/streamlit_reportview.py +++ b/src/vuegen/streamlit_reportview.py @@ -755,14 +755,14 @@ def _generate_dataframe_content(self, dataframe) -> List[str]: r.DataFrameFormat.XLSX.value_with_dot, ]: dataframe_content.append("selected_sheet = 0") - sheet_names = table_utils.get_sheet_names(dataframe.file_path) + sheet_names = table_utils.get_sheet_names(df_file_path.as_posix()) if len(sheet_names) > 1: # If there are multiple sheets, ask the user to select one dataframe_content.append( textwrap.dedent( f"""\ - sheet_names = table_utils.get_sheet_names("{dataframe.file_path}") + sheet_names = table_utils.get_sheet_names("{df_file_path.as_posix()}") selected_sheet = st.selectbox("Select a sheet to display", options=sheet_names) """ ) @@ -775,7 +775,7 @@ def _generate_dataframe_content(self, dataframe) -> List[str]: r.DataFrameFormat.XLSX.value_with_dot, ]: dataframe_content.append( - f"""df = pd.{read_function.__name__}('{dataframe.file_path}', sheet_name=selected_sheet)\n""" + f"""df = pd.{read_function.__name__}('{df_file_path.as_posix()}', sheet_name=selected_sheet)\n""" ) else: dataframe_content.append( From 8a43f902516b72d047724d55d463b227f99bb9c0 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Fri, 20 Jun 2025 16:30:15 +0200 Subject: [PATCH 13/13] =?UTF-8?q?=E2=8F=AA=EF=B8=8F=20Revert=20changes=20o?= =?UTF-8?q?f=20excel=20telative=20pahs=20to=20avoid=20CICD=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuegen/streamlit_reportview.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vuegen/streamlit_reportview.py b/src/vuegen/streamlit_reportview.py index 22da703..69ce63a 100644 --- a/src/vuegen/streamlit_reportview.py +++ b/src/vuegen/streamlit_reportview.py @@ -755,14 +755,14 @@ def _generate_dataframe_content(self, dataframe) -> List[str]: r.DataFrameFormat.XLSX.value_with_dot, ]: dataframe_content.append("selected_sheet = 0") - sheet_names = table_utils.get_sheet_names(df_file_path.as_posix()) + sheet_names = table_utils.get_sheet_names(dataframe.file_path) if len(sheet_names) > 1: # If there are multiple sheets, ask the user to select one dataframe_content.append( textwrap.dedent( f"""\ - sheet_names = table_utils.get_sheet_names("{df_file_path.as_posix()}") + sheet_names = table_utils.get_sheet_names("{dataframe.file_path}") selected_sheet = st.selectbox("Select a sheet to display", options=sheet_names) """ ) @@ -775,7 +775,7 @@ def _generate_dataframe_content(self, dataframe) -> List[str]: r.DataFrameFormat.XLSX.value_with_dot, ]: dataframe_content.append( - f"""df = pd.{read_function.__name__}('{df_file_path.as_posix()}', sheet_name=selected_sheet)\n""" + f"""df = pd.{read_function.__name__}('{dataframe.file_path}', sheet_name=selected_sheet)\n""" ) else: dataframe_content.append(