Skip to content

Commit 1e236f8

Browse files
committed
🚧 add quarto execution for bundle
- execution still fails - convert and render without execution? - add all report types to GUI (for testing) - do not stop app when quarto is not in PATH
1 parent 6444353 commit 1e236f8

File tree

3 files changed

+55
-29
lines changed

3 files changed

+55
-29
lines changed

gui/app.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
app_path = Path(__file__).absolute()
3535
print("app_path:", app_path)
3636

37+
##########################################################################################
38+
# Path to example data dependend on how the GUI is run
3739
if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
3840
# PyInstaller bundeled case
3941
path_to_dat = (
@@ -129,7 +131,6 @@ def radio_button_callback():
129131
# Report type dropdown
130132
# - get list of report types from Enum
131133
report_types = [report_type.value.lower() for report_type in ReportType]
132-
report_types = ["streamlit"] # ! for now, only streamlit is supported
133134
ctk_label_report = customtkinter.CTkLabel(
134135
app,
135136
text="Select type of report to generate (using only streamlit for now)",

src/vuegen/quarto_reportview.py

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def __init__(self, report: r.Report, report_type: r.ReportType):
2525
if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
2626
self.report.logger.info("running in a PyInstaller bundle")
2727
self.BUNDLED_EXECUTION = True
28+
self.report.logger.debug(f"sys._MEIPASS: {sys._MEIPASS}")
2829
else:
2930
self.report.logger.info("running in a normal Python process")
3031

@@ -161,43 +162,64 @@ def run_report(self, output_dir: str = BASE_DIR) -> None:
161162
output_dir : str, optional
162163
The folder where the report was generated (default is 'sections').
163164
"""
164-
try:
165-
if not self.BUNDLED_EXECUTION:
166-
subprocess.run(
167-
[
168-
"quarto",
169-
"render",
170-
os.path.join(output_dir, f"{self.BASE_DIR}.qmd"),
171-
],
172-
check=True,
173-
)
165+
# from quarto_cli import run_quarto # entrypoint of quarto-cli not in module?
166+
167+
file_path_to_qmd = os.path.join(output_dir, f"{self.BASE_DIR}.qmd")
168+
args = ["quarto", "render", file_path_to_qmd]
169+
self.report.logger.info(
170+
f"Running '{self.report.title}' '{self.report_type}' report with {args!r}"
171+
)
172+
if not self.BUNDLED_EXECUTION:
173+
subprocess.run(
174+
args,
175+
check=True,
176+
)
177+
try:
174178
if self.report_type == r.ReportType.JUPYTER:
179+
args = ["quarto", "convert", file_path_to_qmd]
175180
subprocess.run(
176-
[
177-
"quarto",
178-
"convert",
179-
os.path.join(output_dir, f"{self.BASE_DIR}.qmd"),
180-
],
181+
args,
181182
check=True,
182183
)
184+
self.report.logger.info(
185+
f"Converted '{self.report.title}' '{self.report_type}' report to Jupyter Notebook after execution"
186+
)
183187
self.report.logger.info(
184188
f"'{self.report.title}' '{self.report_type}' report rendered"
185189
)
186-
else:
187-
self.report.logger.info(
188-
f"Quarto report '{self.report.title}' '{self.report_type}' cannot "
189-
"be run in a PyInstaller bundle"
190+
except subprocess.CalledProcessError as e:
191+
self.report.logger.error(
192+
f"Error running '{self.report.title}' {self.report_type} report: {str(e)}"
190193
)
191-
except subprocess.CalledProcessError as e:
192-
self.report.logger.error(
193-
f"Error running '{self.report.title}' {self.report_type} report: {str(e)}"
194+
raise
195+
except FileNotFoundError as e:
196+
self.report.logger.error(
197+
f"Quarto is not installed. Please install Quarto to run the report: {str(e)}"
198+
)
199+
raise
200+
else:
201+
quarto_path = Path(sys._MEIPASS) / "quarto_cli" / "bin" / "quarto"
202+
if sys.platform == "win32":
203+
# ! to check
204+
quarto_path = self.quarto_path.with_suffix(".exe")
205+
self.report.logger.info(f"quarto_path: {quarto_path}")
206+
207+
args = [f"{quarto_path}", "convert", file_path_to_qmd]
208+
subprocess.run(
209+
args,
210+
check=True,
194211
)
195-
raise
196-
except FileNotFoundError as e:
197-
self.report.logger.error(
198-
f"Quarto is not installed. Please install Quarto to run the report: {str(e)}"
212+
self.report.logger.info(
213+
f"Converted '{self.report.title}' '{self.report_type}' report to Jupyter Notebook after execution"
214+
)
215+
notebook_filename = Path(file_path_to_qmd).with_suffix(".ipynb")
216+
# ipynb will not be executed per default
217+
# ! check if execution works although qmd cannot be executed...
218+
args = [f"{quarto_path}", "render", notebook_filename]
219+
subprocess.run(
220+
args,
221+
check=True,
199222
)
200-
raise
201223

202224
def _create_yaml_header(self) -> str:
203225
"""

src/vuegen/report_generator.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
import shutil
3+
import sys
34

45
from .config_manager import ConfigManager
56
from .quarto_reportview import QuartoReportView
@@ -67,7 +68,9 @@ def get_report(
6768

6869
else:
6970
# Check if Quarto is installed
70-
if shutil.which("quarto") is None:
71+
if shutil.which("quarto") is None and not hasattr(
72+
sys, "_MEIPASS"
73+
): # ? and not getattr(sys, "frozen", False)
7174
logger.error(
7275
"Quarto is not installed. Please install Quarto before generating this report type."
7376
)

0 commit comments

Comments
 (0)