Skip to content

Commit 56fa147

Browse files
authored
Merge branch 'main' into split-readme-docs
2 parents 11403ef + 456e65b commit 56fa147

File tree

5 files changed

+61
-20
lines changed

5 files changed

+61
-20
lines changed

.github/workflows/cdci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ jobs:
155155
- name: Build executable
156156
run: |
157157
cd gui
158-
pyinstaller -n vuegen_gui --onefile --windowed --collect-all pyvis --collect-all streamlit --collect-all st_aggrid --collect-all customtkinter --collect-all quarto_cli --collect-all plotly --collect-all _plotly_utils --collect-all traitlets --collect-all referencing --collect-all rpds --collect-all tenacity --collect-all pyvis --collect-all pandas --collect-all numpy --collect-all matplotlib --collect-all openpyxl --collect-all xlrd --collect-all nbformat --collect-all nbclient --collect-all altair --collect-all itables --collect-all kaleido --collect-all pyarrow --collect-all dataframe_image --collect-all narwhals --collect-all PIL --collect-all vl_convert --add-data ../docs/example_data/Basic_example_vuegen_demo_notebook:example_data/Basic_example_vuegen_demo_notebook --add-data ../docs/images/vuegen_logo.png:. app.py
158+
pyinstaller -n vuegen_gui --onefile --windowed --collect-all pyvis --collect-all streamlit --collect-all st_aggrid --collect-all customtkinter --collect-all quarto_cli --collect-all plotly --collect-all _plotly_utils --collect-all traitlets --collect-all referencing --collect-all rpds --collect-all tenacity --collect-all pandas --collect-all numpy --collect-all matplotlib --collect-all openpyxl --collect-all xlrd --collect-all nbformat --collect-all nbclient --collect-all altair --collect-all itables --collect-all kaleido --collect-all pyarrow --collect-all dataframe_image --collect-all narwhals --collect-all PIL --collect-all vl_convert --collect-all typing-extensions --add-data ../docs/example_data/Basic_example_vuegen_demo_notebook:example_data/Basic_example_vuegen_demo_notebook --add-data ../docs/images/vuegen_logo.png:. app.py
159159
# --windowed only for mac, see:
160160
# https://pyinstaller.org/en/stable/usage.html#building-macos-app-bundles
161161
# 'Under macOS, PyInstaller always builds a UNIX executable in dist.'

README.md

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ vuegen --directory docs/example_data/Earth_microbiome_vuegen_demo_notebook --rep
119119
Your input directory must follow a **nested folder structure**, where first-level folders are treated as **sections** and second-level folders as **subsections**, containing the components (plots, tables, networks, Markdown text, and HTML files).
120120

121121
Here is an example layout:
122+
122123
```
123124
report_folder/
124125
├── section1/
@@ -138,7 +139,7 @@ report_folder/
138139
> [!WARNING]
139140
> VueGen currently requires each section to contain at least one subsection folder. Defining only sections (with no subsections) or using deeper nesting levels (i.e., sub-subsections) will result in errors. In upcoming releases, we plan to support more flexible directory structures.
140141
141-
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.
142+
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.
142143
The order of sections, subsections, and components can be defined using numerical suffixes in folder and file names.
143144

144145
It's also possible to provide a configuration file instead of a directory:
@@ -206,6 +207,10 @@ from the releases page according to your operating system.
206207

207208
```bash
208209
conda create -n vuegen_gui -c conda-forge python=3.12 jupyter
210+
# in case you have errors, install vuegen addtionally
211+
conda activate vuegen_gui
212+
pip install vuegen
213+
# list all conda environments to find the location of the environment
209214
conda info -e # find environment location
210215
```
211216

@@ -258,25 +263,26 @@ This case study highlights VueGen’s capability to embed a chatbot component in
258263
enabling interactive conversations inside the report. This component is streamlit-specific and is not
259264
available for other report types.
260265

266+
261267
Two API modes are supported:
262268

263269
- **Ollama-style streaming chat completion**
264-
If a `model` parameter is specified in the config file, VueGen assumes the chatbot is using Ollama’s [/api/chat endpoint][ollama_chat].
265-
Messages are handled as chat history, and the assistant responses are streamed in real time for a smooth and responsive experience.
266-
This mode supports LLMs such as `llama3`, `deepsek`, or `mistral`.
270+
If a `model` parameter is specified in the config file, VueGen assumes the chatbot is using Ollama’s [/api/chat endpoint][ollama_chat].
271+
Messages are handled as chat history, and the assistant responses are streamed in real time for a smooth and responsive experience.
272+
This mode supports LLMs such as `llama3`, `deepsek`, or `mistral`.
267273

268274
> [!TIP]
269275
> See [Ollama’s website][ollama] for more details.
270276
271277
- **Standard prompt-response API**
272-
If no `model` is provided, VueGen uses a simpler prompt-response flow.
273-
A single prompt is sent to an endpoint, and a structured JSON object is expected in return.
274-
Currently, the response can include:
278+
If no `model` is provided, VueGen uses a simpler prompt-response flow.
279+
A single prompt is sent to an endpoint, and a structured JSON object is expected in return.
280+
Currently, the response can include:
275281
- `text`: the main textual reply
276282
- `links`: a list of source URLs (optional)
277283
- `HTML content`: an HTML snippet with a Pyvis network visualization (optional)
278284

279-
This response structure is currently customized for an internal knowledge graph assistant, but VueGen is being actively developed
285+
This response structure is currently customized for an internal knowledge graph assistant, but VueGen is being actively developed
280286
to support more flexible and general-purpose response formats in future releases.
281287

282288
> [!NOTE]

gui/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ bundle:
3737
--collect-all rpds \
3838
--collect-all tenacity \
3939
--collect-all vl_convert \
40+
--collect-all typing-extensions \
4041
--add-data ../docs/example_data/Basic_example_vuegen_demo_notebook:example_data/Basic_example_vuegen_demo_notebook \
4142
--add-data ../docs/images/vuegen_logo.png:. \
4243
app.py
@@ -80,7 +81,6 @@ bundle:
8081
# --collect-all urllib3 \
8182
# --collect-all uri-template \
8283
# --collect-all tzdata \
83-
# --collect-all typing-extensions\
8484
# --collect-all types-python-dateutil \
8585
# --collect-all traitlets \
8686
# --collect-all tornado \

gui/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def inner():
170170
f"\n\nConfiguration file at:\n{gen_config_path}",
171171
)
172172
global hash_config_app # ! fix this
173-
get_completion_message(report_type.get())
173+
get_completion_message(report_type.get(), config_path=gen_config_path)
174174
if hash(yaml.dump(config_app)) != hash_config_app:
175175
with open(config_file, "w", encoding="utf-8") as f:
176176
yaml.dump(config_app, f)

src/vuegen/streamlit_reportview.py

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
2-
import re
32
import subprocess
43
import sys
4+
import textwrap
55
from pathlib import Path
66
from typing import List
77

@@ -75,16 +75,33 @@ def generate_report(
7575
self.report.logger.debug("Processing app navigation code.")
7676
# Define the Streamlit imports and report manager content
7777
report_manag_content = []
78+
report_manag_content.append(
79+
textwrap.dedent(
80+
"""\
81+
import os
82+
import time
83+
84+
import psutil
85+
import streamlit as st
86+
"""
87+
)
88+
)
7889
if self.report.logo:
7990
report_manag_content.append(
80-
f"""import streamlit as st\n
81-
st.set_page_config(layout="wide", page_title="{self.report.title}", page_icon="{self.report.logo}")
82-
st.logo("{self.report.logo}")"""
91+
textwrap.dedent(
92+
f"""\
93+
st.set_page_config(layout="wide", page_title="{self.report.title}", page_icon="{self.report.logo}")
94+
st.logo("{self.report.logo}")
95+
"""
96+
)
8397
)
8498
else:
8599
report_manag_content.append(
86-
f"""import streamlit as st\n
87-
st.set_page_config(layout="wide", page_title="{self.report.title}")"""
100+
textwrap.dedent(
101+
f"""\
102+
st.set_page_config(layout="wide", page_title="{self.report.title}")
103+
"""
104+
)
88105
)
89106
report_manag_content.append(
90107
self._format_text(
@@ -142,12 +159,30 @@ def generate_report(
142159

143160
# Add navigation object to the home page content
144161
report_manag_content.append(
145-
f"""report_nav = st.navigation(sections_pages)
146-
report_nav.run()"""
162+
textwrap.dedent(
163+
"""\
164+
report_nav = st.navigation(sections_pages)
165+
166+
# Following https://discuss.streamlit.io/t/close-streamlit-app-with-button-click/35132/5
167+
exit_app = st.sidebar.button("Shut Down App", icon=":material/power_off:", use_container_width=True)
168+
if exit_app:
169+
st.toast("Shutting down the app...")
170+
time.sleep(1)
171+
# Terminate streamlit python process
172+
pid = os.getpid()
173+
p = psutil.Process(pid)
174+
p.terminate()
175+
176+
177+
report_nav.run()
178+
"""
179+
)
147180
)
148181

149182
# Write the navigation and general content to a Python file
150-
with open(Path(output_dir) / self.REPORT_MANAG_SCRIPT, "w") as nav_manager:
183+
with open(
184+
Path(output_dir) / self.REPORT_MANAG_SCRIPT, "w", encoding="utf8"
185+
) as nav_manager:
151186
nav_manager.write("\n".join(report_manag_content))
152187
self.report.logger.info(
153188
f"Created app navigation script: {self.REPORT_MANAG_SCRIPT}"

0 commit comments

Comments
 (0)