Skip to content

Commit 37cc80f

Browse files
committed
🎨 use textwrap to keep indentation
1 parent 57948ec commit 37cc80f

File tree

1 file changed

+103
-55
lines changed

1 file changed

+103
-55
lines changed

src/vuegen/streamlit_reportview.py

Lines changed: 103 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ def generate_report(self, output_dir: str = SECTIONS_DIR) -> None:
119119
"""\
120120
import os
121121
import time
122-
123-
import psutil
122+
123+
import psutil
124124
import streamlit as st
125125
"""
126126
)
@@ -129,7 +129,10 @@ def generate_report(self, output_dir: str = SECTIONS_DIR) -> None:
129129
report_manag_content.append(
130130
textwrap.dedent(
131131
f"""\
132-
st.set_page_config(layout="wide", page_title="{self.report.title}", page_icon="{self.report.logo}")
132+
st.set_page_config(layout="wide",
133+
page_title="{self.report.title}",
134+
page_icon="{self.report.logo}"
135+
)
133136
st.logo("{self.report.logo}")
134137
"""
135138
)
@@ -138,7 +141,8 @@ def generate_report(self, output_dir: str = SECTIONS_DIR) -> None:
138141
report_manag_content.append(
139142
textwrap.dedent(
140143
f"""\
141-
st.set_page_config(layout="wide", page_title="{self.report.title}")
144+
st.set_page_config(layout="wide",
145+
page_title="{self.report.title}")
142146
"""
143147
)
144148
)
@@ -227,9 +231,12 @@ def generate_report(self, output_dir: str = SECTIONS_DIR) -> None:
227231
textwrap.dedent(
228232
"""\
229233
report_nav = st.navigation(sections_pages)
230-
231-
# Following https://discuss.streamlit.io/t/close-streamlit-app-with-button-click/35132/5
232-
exit_app = st.sidebar.button("Shut Down App", icon=":material/power_off:", use_container_width=True)
234+
235+
# Following https://discuss.streamlit.io/t/\
236+
close-streamlit-app-with-button-click/35132/5
237+
exit_app = st.sidebar.button("Shut Down App",
238+
icon=":material/power_off:",
239+
use_container_width=True)
233240
if exit_app:
234241
st.toast("Shutting down the app...")
235242
time.sleep(1)
@@ -238,7 +245,7 @@ def generate_report(self, output_dir: str = SECTIONS_DIR) -> None:
238245
p = psutil.Process(pid)
239246
p.terminate()
240247
241-
248+
242249
report_nav.run()
243250
"""
244251
)
@@ -367,7 +374,17 @@ def _format_text(
367374
raise ValueError(
368375
f"Unsupported text type: {type}. Supported types are 'header', "
369376
"'paragraph', and 'caption'."
370-
)
377+
378+
return textwrap.dedent(
379+
f"""
380+
st.markdown(
381+
(
382+
"<{tag} style='text-align: {text_align}; "
383+
"color: {color};'>{text}</{tag}>"
384+
),
385+
unsafe_allow_html=True)
386+
"""
387+
)
371388

372389
def _generate_home_section(
373390
self,
@@ -665,9 +682,16 @@ def _generate_plot_content(self, plot) -> List[str]:
665682

666683
# Append the code for additional information (nodes and edges count)
667684
plot_content.append(
668-
f"""
669-
st.markdown(f"<p style='text-align: center; color: black;'> <b>Number of nodes:</b> {num_nodes} </p>", unsafe_allow_html=True)
670-
st.markdown(f"<p style='text-align: center; color: black;'> <b>Number of relationships:</b> {num_edges} </p>", unsafe_allow_html=True)\n"""
685+
textwrap.dedent(
686+
f"""
687+
st.markdown(("<p style='text-align: center; color: black;'> "
688+
f"<b>Number of nodes:</b> {num_nodes} </p>"),
689+
unsafe_allow_html=True)
690+
st.markdown(("<p style='text-align: center; color: black;'>"
691+
f" <b>Number of relationships:</b> {num_edges} </p>"),
692+
unsafe_allow_html=True)
693+
"""
694+
)
671695
)
672696

673697
# Add the specific code for visualization
@@ -703,37 +727,51 @@ def _generate_plot_code(self, plot) -> str:
703727
"""
704728
# If the file path is a URL, generate code to fetch content via requests
705729
if is_url(plot.file_path):
706-
plot_code = f"""
707-
response = requests.get('{plot.file_path}')
708-
response.raise_for_status()
709-
plot_json = json.loads(response.text)\n"""
730+
plot_code = textwrap.dedent(
731+
f"""
732+
response = requests.get('{plot.file_path}')
733+
response.raise_for_status()
734+
plot_json = json.loads(response.text)\n"""
735+
)
710736
else: # If it's a local file
711737
plot_rel_path = get_relative_file_path(plot.file_path)
712-
plot_code = f"""
713-
with open('{plot_rel_path.as_posix()}', 'r') as plot_file:
714-
plot_json = json.load(plot_file)\n"""
738+
plot_code = textwrap.dedent(
739+
f"""
740+
with open('{plot_rel_path.as_posix()}', 'r') as plot_file:
741+
plot_json = json.load(plot_file)\n"""
742+
)
715743

716744
# Add specific code for each visualization tool
717745
if plot.plot_type == r.PlotType.PLOTLY:
718-
plot_code += """
719-
# Keep only 'data' and 'layout' sections
720-
plot_json = {key: plot_json[key] for key in plot_json if key in ['data', 'layout']}
721-
722-
# Remove 'frame' section in 'data'
723-
plot_json['data'] = [{k: v for k, v in entry.items() if k != 'frame'} for entry in plot_json.get('data', [])]
724-
st.plotly_chart(plot_json, use_container_width=True)\n"""
746+
plot_code += textwrap.dedent(
747+
"""
748+
# Keep only 'data' and 'layout' sections
749+
plot_json = {key: plot_json[key] for key in plot_json
750+
if key in ['data', 'layout']}
751+
752+
# Remove 'frame' section in 'data'
753+
plot_json['data'] = [{k: v for k, v in entry.items() if k != 'frame'}
754+
for entry in plot_json.get('data', [])]
755+
st.plotly_chart(plot_json, use_container_width=True)\n"""
756+
)
725757

726758
elif plot.plot_type == r.PlotType.ALTAIR:
727-
plot_code += """
728-
altair_plot = alt.Chart.from_dict(plot_json)
729-
st.vega_lite_chart(json.loads(altair_plot.to_json()), use_container_width=True)\n"""
759+
plot_code += textwrap.dedent(
760+
"""
761+
altair_plot = alt.Chart.from_dict(plot_json)
762+
st.vega_lite_chart(json.loads(altair_plot.to_json()),
763+
use_container_width=True)\n"""
764+
)
730765

731766
elif plot.plot_type == r.PlotType.INTERACTIVE_NETWORK:
732-
plot_code = """# Streamlit checkbox for controlling the layout
733-
control_layout = st.checkbox('Add panel to control layout', value=True)
734-
net_html_height = 1200 if control_layout else 630
735-
# Load HTML into HTML component for display on Streamlit
736-
st.components.v1.html(html_content, height=net_html_height)\n"""
767+
plot_code = textwrap.dedent(
768+
"""\
769+
# Streamlit checkbox for controlling the layout
770+
control_layout = st.checkbox('Add panel to control layout', value=True)
771+
net_html_height = 1200 if control_layout else 630
772+
# Load HTML into HTML component for display on Streamlit
773+
st.components.v1.html(html_content, height=net_html_height)\n"""
774+
)
737775
return plot_code
738776

739777
def _generate_dataframe_content(self, dataframe) -> List[str]:
@@ -796,7 +834,8 @@ def _generate_dataframe_content(self, dataframe) -> List[str]:
796834
textwrap.dedent(
797835
f"""\
798836
sheet_names = table_utils.get_sheet_names("{dataframe.file_path}")
799-
selected_sheet = st.selectbox("Select a sheet to display", options=sheet_names)
837+
selected_sheet = st.selectbox("Select a sheet to display",
838+
options=sheet_names)
800839
"""
801840
)
802841
)
@@ -818,26 +857,35 @@ def _generate_dataframe_content(self, dataframe) -> List[str]:
818857
# ! Alternative to select box: iterate over sheets in DataFrame
819858
# Displays a DataFrame using AgGrid with configurable options.
820859
dataframe_content.append(
821-
"""
822-
# Displays a DataFrame using AgGrid with configurable options.
823-
grid_builder = GridOptionsBuilder.from_dataframe(df)
824-
grid_builder.configure_default_column(editable=True, groupable=True, filter=True)
825-
grid_builder.configure_side_bar(filters_panel=True, columns_panel=True)
826-
grid_builder.configure_selection(selection_mode="multiple")
827-
grid_builder.configure_pagination(enabled=True, paginationAutoPageSize=False, paginationPageSize=20)
828-
grid_options = grid_builder.build()
829-
830-
AgGrid(df, gridOptions=grid_options, enable_enterprise_modules=True)
831-
832-
# Button to download the df
833-
df_csv = df.to_csv(sep=',', header=True, index=False).encode('utf-8')
834-
st.download_button(
835-
label="Download dataframe as CSV",
836-
data=df_csv,
837-
file_name=f"dataframe_{df_index}.csv",
838-
mime='text/csv',
839-
key=f"download_button_{df_index}")
840-
df_index += 1"""
860+
textwrap.dedent(
861+
"""
862+
# Displays a DataFrame using AgGrid with configurable options.
863+
grid_builder = GridOptionsBuilder.from_dataframe(df)
864+
grid_builder.configure_default_column(editable=True,
865+
groupable=True,
866+
filter=True,
867+
)
868+
grid_builder.configure_side_bar(filters_panel=True,
869+
columns_panel=True)
870+
grid_builder.configure_selection(selection_mode="multiple")
871+
grid_builder.configure_pagination(enabled=True,
872+
paginationAutoPageSize=False,
873+
paginationPageSize=20,
874+
)
875+
grid_options = grid_builder.build()
876+
877+
AgGrid(df, gridOptions=grid_options, enable_enterprise_modules=True)
878+
879+
# Button to download the df
880+
df_csv = df.to_csv(sep=',', header=True, index=False).encode('utf-8')
881+
st.download_button(
882+
label="Download dataframe as CSV",
883+
data=df_csv,
884+
file_name=f"dataframe_{df_index}.csv",
885+
mime='text/csv',
886+
key=f"download_button_{df_index}")
887+
df_index += 1"""
888+
)
841889
)
842890
except Exception as e:
843891
self.report.logger.error(

0 commit comments

Comments
 (0)