Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
9558a7d
:art: format markdowns
enryH Jun 19, 2025
ca5a970
:art: docstrings to 90 characters and remove whitespaces
enryH Jun 19, 2025
04e4d54
:wrench: set line length to 90 characters
enryH Jun 19, 2025
e4c5881
:art: split comments, add comments, remove more whitespace, add more …
enryH Jun 19, 2025
5a909bb
:art: write strings on two line and let Python concatenate theses
enryH Jun 19, 2025
c2a0016
:art: snake_case
enryH Jun 19, 2025
4cc06c0
:art: raise ValueError if unknown type is provided
enryH Jun 19, 2025
57948ec
:art: specify encoding explicitly
enryH Jun 19, 2025
37cc80f
:art: use textwrap to keep indentation
enryH Jun 19, 2025
a0c4ca2
:bug: with textwrap the text cannot contain new line statements
enryH Jun 19, 2025
05b0d98
:art: adjust comments and docstrings to line-length
enryH Jun 20, 2025
f7f26d3
:wrench: add jupytext configuration for notebooks to project
enryH Jun 20, 2025
21470b3
Merge branch 'main' into styling_formating
enryH Jun 21, 2025
bc47b96
Merge branch 'main' into styling_formating
enryH Jun 25, 2025
a9ace37
Merge branch 'main' into styling_formating
enryH Jun 25, 2025
1d9855e
✅ update example report files so test pass (reviewed changes are only…
enryH Jun 25, 2025
f257178
:art: continue reformatting of streamlit_report.py
enryH Jun 25, 2025
a38262e
:art: remove one level of indentation
enryH Jun 25, 2025
700217a
:art: docstring and f-string formatting
enryH Jun 25, 2025
a606456
:art: encoding and whitespace updates
enryH Jun 25, 2025
9d3528e
:bug: add missing argument to abc for reports
enryH Jun 25, 2025
5fb9049
:art: textwrap code or html blocks
enryH Jun 25, 2025
206deab
:art: keep urls at the top
enryH Jun 25, 2025
ed1132d
:art: limit remaining lines to 90 characters
enryH Jun 25, 2025
518ff91
:art: shorten docstrings and comments, implement lazy logging
enryH Jun 26, 2025
e2a9da1
:art: remove trailing white-space from streamlit footer
enryH Jun 26, 2025
85e2c53
:truck: add constants file to keep these central
enryH Jun 26, 2025
37eceb0
:art: streamlit footer in utils? use central constants for footer, de…
enryH Jun 26, 2025
66818f5
:art: add initialization of dictionary in body of function
enryH Jun 26, 2025
4ef3f7d
:art: add timeout to get request -> will 60 seconds always be enough?
enryH Jun 26, 2025
732e1fe
:art: dedent and slightly modify completion message
enryH Jun 26, 2025
a808217
:art: line lenght, lazy logging and raising exceptions from exception
enryH Jun 26, 2025
6c66f42
:art: module and docstrings, comments splitting and removing unnecess…
enryH Jun 26, 2025
60afba6
:art: lazy logging + exe_info and Error messaging splitting (line len…
enryH Jun 26, 2025
4ac1971
:art: module string, line length, unused arguments,
enryH Jun 26, 2025
36cbc20
:art: lazy logging and reporting of error info for error
enryH Jun 27, 2025
259f4f5
🐛 Handle error for loading static images from a URL in streamlit reports
sayalaruano Jun 30, 2025
f66f8b8
📝 Update md files for the yaml examples on the documentation
sayalaruano Jun 30, 2025
c4a58e8
🐛 Fix desciption from the EMP config example
sayalaruano Jun 30, 2025
c6d088e
🐛 Fix code to load images from URLs in streamlit reports
sayalaruano Jun 30, 2025
0c3443b
Trigger GitHub actions to avoid connection error to download tinytex
sayalaruano Jun 30, 2025
317f55f
:art::wrench: let ruff check for line lenght and other potential bugs…
enryH Jun 30, 2025
1736bac
:bug: Ollama chatbot example
enryH Jun 30, 2025
80332cd
:bug: use existing config file, not the local one generated by chabot…
enryH Jun 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/cdci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ jobs:
echo "Error: One or more protected files have been modified."
exit 1
fi
- name: check streamlit report files for chatbot API
run: |
vuegen -c docs/example_config_files/Chatbot_example_config.yaml -output_dir tests/report_examples/chat_bot
if git diff tests/report_examples | grep .; then
echo Failed for report: $format
echo "Error: One or more protected files have been modified."
exit 1
fi
- name: check for changes in report files
run: |
# write streamlit report to test folder
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ cython_debug/
# Temporary files
logs/
vuegen/logs/
./streamlit_report/
streamlit_report/
!tests/report_examples
quarto_report/
output_docker/
Expand Down
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"editor.rulers": [88, 100, 120]
}
16 changes: 8 additions & 8 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Docs creation

In order to build the docs you need to
In order to build the docs you need to

1. Install sphinx and additional support packages
2. Build the package reference files
3. Run sphinx to create a local html version
1. Install sphinx and additional support packages
2. Build the package reference files
3. Run sphinx to create a local html version

The documentation is build using readthedocs automatically.

Expand All @@ -18,12 +18,13 @@ poetry install --with docs

## Build docs using Sphinx command line tools

Command to be run from `path/to/docs`, i.e. from within the `docs` package folder:
Command to be run from `path/to/docs`, i.e. from within the `docs` package folder:

Options:
- `--separate` to build separate pages for each (sub-)module

```bash
- `--separate` to build separate pages for each (sub-)module

```bash
# pwd: docs
# apidoc
sphinx-apidoc --force --implicit-namespaces --module-first -o reference ../src/vuegen
Expand All @@ -38,4 +39,3 @@ The README is included in the `Overview` section of the docs. We created a [Pyth
Relative links are used in the main README, which need to be resolved when building. It's
possible to include the a `relative-docs` option if one uses `index.md` ([see docs](https://myst-parser.readthedocs.io/en/latest/faq/index.html#include-a-file-from-outside-the-docs-folder-like-readme-md)). This does not work
with `href` links, only native markdown links.

2 changes: 1 addition & 1 deletion docs/example_config_files/Chatbot_example_config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
report:
title: Chatbot example
description: >
A chatbot exaple.
A chatbot example.
sections:
- title: ChatBot test
subsections:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
report:
title: Earth Microbiome Vuegen Demo Notebook
description: "The Earth Microbiome Project (EMP) is a systematic attempt to characterize\
\ global microbial taxonomic and functional diversity for the benefit of the planet\
\ and humankind. \n It aimed to sample the Earth\u2019s microbial communities\
\ at an unprecedented scale in order to advance our understanding of the organizing\
\ biogeographic principles that govern microbial community structure. \n The\
\ EMP dataset is generated from samples that individual researchers have compiled\
\ and contributed to the EMP. \n The result is both a reference database giving\
\ global context to DNA sequence data and a framework for incorporating data from\
\ future studies, fostering increasingly complete characterization of Earth\u2019\
s microbial diversity.\n \n You can find more information about the Earth Microbiome\
\ Project at https://earthmicrobiome.org/ and in the [original article](https://www.nature.com/articles/nature24621).\n"
description: >
The Earth Microbiome Project (EMP) is a systematic attempt to characterize global
microbial taxonomic and functional diversity for the benefit of the planet and humankind.
It aimed to sample the Earth’s microbial communities at an unprecedented scale in order to
advance our understanding of the organizing biogeographic principles that govern microbial
community structure. The EMP dataset is generated from samples that individual researchers
have compiled and contributed to the EMP. The result is both a reference database giving
global context to DNA sequence data and a framework for incorporating data from future
studies, fostering increasingly complete characterization of Earth’s microbial diversity.
You can find more information about the Earth Microbiome Project at https://earthmicrobiome.org/
and in the original article at https://www.nature.com/articles/nature24621.
graphical_abstract: https://raw.githubusercontent.com/ElDeveloper/cogs220/master/emp-logo.svg
logo: https://raw.githubusercontent.com/ElDeveloper/cogs220/master/emp-logo.svg
sections:
Expand Down
6 changes: 3 additions & 3 deletions docs/vuegen_basic_case_study_configfile.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Predefined Directory Case Study - Configuration File

The [configuration file](https://github.com/Multiomics-Analytics-Group/vuegen/blob/main/docs/example_config_files/Basic_example_vuegen_demo_notebook_config.yaml) of the basic case study using a predefined directory is presented below:
The [configuration file](https://github.com/Multiomics-Analytics-Group/vuegen/blob/main/docs/example_config_files/Basic_example_vuegen_demo_notebook_config.yaml) of the basic case study using a predefined directory is presented below:

```yaml
report:
title: Basic Example Vuegen Demo Notebook
description: A general description of the report.
graphical_abstract: https://raw.githubusercontent.com/Multiomics-Analytics-Group/vuegen/main/docs/images/vuegen_logo.svg
logo: https://raw.githubusercontent.com/Multiomics-Analytics-Group/vuegen/main/docs/images/vuegen_logo.svg
graphical_abstract: https://raw.githubusercontent.com/Multiomics-Analytics-Group/vuegen/main/docs/images/vuegen_logo.png
logo: https://raw.githubusercontent.com/Multiomics-Analytics-Group/vuegen/main/docs/images/vuegen_logo.png
sections:
- title: Plots
description: This section contains example plots.
Expand Down
25 changes: 12 additions & 13 deletions docs/vuegen_earth_microbiome_case_study_configfile.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ The [configuration file](https://github.com/Multiomics-Analytics-Group/vuegen/bl
```yaml
report:
title: Earth Microbiome Vuegen Demo Notebook
description: "The Earth Microbiome Project (EMP) is a systematic attempt to characterize\
\ global microbial taxonomic and functional diversity for the benefit of the planet\
\ and humankind. \n It aimed to sample the Earth\u2019s microbial communities\
\ at an unprecedented scale in order to advance our understanding of the organizing\
\ biogeographic principles that govern microbial community structure. \n The\
\ EMP dataset is generated from samples that individual researchers have compiled\
\ and contributed to the EMP. \n The result is both a reference database giving\
\ global context to DNA sequence data and a framework for incorporating data from\
\ future studies, fostering increasingly complete characterization of Earth\u2019\
s microbial diversity.\n \n You can find more information about the Earth Microbiome\
\ Project at https://earthmicrobiome.org/ and in the [original article](https://www.nature.com/articles/nature24621).\n"
description: >
The Earth Microbiome Project (EMP) is a systematic attempt to characterize global
microbial taxonomic and functional diversity for the benefit of the planet and humankind.
It aimed to sample the Earth’s microbial communities at an unprecedented scale in order to
advance our understanding of the organizing biogeographic principles that govern microbial
community structure. The EMP dataset is generated from samples that individual researchers
have compiled and contributed to the EMP. The result is both a reference database giving
global context to DNA sequence data and a framework for incorporating data from future
studies, fostering increasingly complete characterization of Earth’s microbial diversity.
You can find more information about the Earth Microbiome Project at https://earthmicrobiome.org/
and in the original article at https://www.nature.com/articles/nature24621.
graphical_abstract: https://raw.githubusercontent.com/ElDeveloper/cogs220/master/emp-logo.svg
logo: https://raw.githubusercontent.com/ElDeveloper/cogs220/master/emp-logo.svg
sections:
Expand Down Expand Up @@ -128,8 +128,7 @@ sections:
component_type: PLOT
plot_type: STATIC
- title: Shanon entropy analysis
description: This subsection contains the Shannon entropy analysis of the EMP
dataset.
description: This subsection contains the Shannon entropy analysis of the EMP dataset.
components:
- title: Specificity of sequences and higher taxonomic groups for environment
file_path: https://raw.githubusercontent.com/biocore/emp/master/methods/images/figure4_entropy.png
Expand Down
17 changes: 17 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,20 @@ vuegen = "vuegen.__main__:main"

[tool.isort]
profile = "black"

[tool.jupytext]
formats = "ipynb,py:percent"

[tool.ruff]
# Allow lines to be as long as:
line-length = 88

[tool.ruff.lint]
# https://docs.astral.sh/ruff/tutorial/#rule-selection
# 1. Enable flake8-bugbear (`B`) rules
# 2. Enable pycodestyle (`E`) errors and (`W`) warnings
# 3. Pyflakes (`F`) errors
extend-select = ["E", "W", 'F', 'B']

[tool.black]
line-length = 88
4 changes: 4 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[flake8]
exclude = docs
max-line-length = 88
aggressive = 2
5 changes: 5 additions & 0 deletions src/vuegen/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
"""VueGen automates the creation of reports from bioinformatics outputs,
supporting formats like PDF, HTML, DOCX, ODT, PPTX, Reveal.js, Jupyter notebooks,
and Streamlit web applications. Users simply provide a directory with output files
and VueGen compiles them into a structured report."""

__version__ = "1.0.0"
2 changes: 2 additions & 0 deletions src/vuegen/__main__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""Command-line interface for VueGen report generation."""

import sys
from pathlib import Path

Expand Down
54 changes: 38 additions & 16 deletions src/vuegen/config_manager.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""ConfigManage creates configuration files from folders and can create components
for reports from YAML config files.
"""

import json
import logging
import os
Expand All @@ -10,7 +14,8 @@

class ConfigManager:
"""
Class for handling metadata of reports from YAML config file and creating report objects.
Class for handling metadata of reports from YAML config file and creating report
objects.
"""

def __init__(self, logger: Optional[logging.Logger] = None, max_depth: int = 2):
Expand All @@ -20,10 +25,11 @@ def __init__(self, logger: Optional[logging.Logger] = None, max_depth: int = 2):
Parameters
----------
logger : logging.Logger, optional
A logger instance for the class. If not provided, a default logger will be created.
A logger instance for the class.
If not provided, a default logger will be created.
max_depth : int, optional
The maximum depth of the directory structure to consider when generating the report
config from a directory.
The maximum depth of the directory structure to consider when generating
the report config from a directory.
The default is 2, which means it will include sections and subsections.
"""
if logger is None:
Expand Down Expand Up @@ -53,7 +59,8 @@ def _create_title_fromdir(self, file_dirname: str) -> str:

def _create_component_config_fromfile(self, file_path: Path) -> Dict[str, str]:
"""
Infers a component config from a file, including component type, plot type, and additional fields.
Infers a component config from a file, including component type, plot type,
and additional fields.

Parameters
----------
Expand Down Expand Up @@ -144,21 +151,27 @@ def _create_component_config_fromfile(self, file_path: Path) -> Dict[str, str]:
else:
component_config["plot_type"] = r.PlotType.PLOTLY.value
except Exception as e:
self.logger.warning(f"Could not parse JSON file {file_path}: {e}")
self.logger.warning(
"Could not parse JSON file %s: %s", file_path, e, exc_info=True
)
component_config["plot_type"] = "unknown"
elif file_ext == ".md":
component_config["component_type"] = r.ComponentType.MARKDOWN.value
else:
if not file_ext:
# hidden files starting with a dot
file_ext = file_path.name
self.logger.error(
f"Unsupported file extension: {file_ext}. Skipping file: {file_path}"
"Unsupported file extension: %s. Skipping file: %s", file_ext, file_path
)
return None

return component_config

def _sort_paths_by_numprefix(self, paths: List[Path]) -> List[Path]:
"""
Sorts a list of Paths by numeric prefixes in their names, placing non-numeric items at the end.
Sorts a list of Paths by numeric prefixes in their names, placing non-numeric
items at the end.

Parameters
----------
Expand Down Expand Up @@ -239,7 +252,8 @@ def _create_subsect_config_fromdir(
continue
# components are added to subsection
# ! Alternatively, one could add (sub-)sections to the subsection
# ? Then one could remove differentiation between sections and subsections
# ? Then one could remove differentiation between sections and
# ? subsections
nested_components = self._create_subsect_config_fromdir(file, level + 1)
components.extend(nested_components["components"])

Expand Down Expand Up @@ -298,7 +312,8 @@ def create_yamlconfig_fromdir(
self, base_dir: str
) -> Tuple[Dict[str, Union[str, List[Dict]]], Path]:
"""
Generates a YAML-compatible config file from a directory. It also returns the resolved folder path.
Generates a YAML-compatible config file from a directory. It also returns the
resolved folder path.

Parameters
----------
Expand Down Expand Up @@ -361,7 +376,8 @@ def create_yamlconfig_fromdir(

def initialize_report(self, config: dict) -> tuple[r.Report, dict]:
"""
Extracts report metadata from a YAML config file and returns a Report object and the raw metadata.
Extracts report metadata from a YAML config file and returns a Report object and
the raw metadata.

Parameters
----------
Expand All @@ -371,7 +387,8 @@ def initialize_report(self, config: dict) -> tuple[r.Report, dict]:
Returns
-------
report, config : tuple[Report, dict]
A tuple containing the Report object created from the YAML config file and the raw metadata dictionary.
A tuple containing the Report object created from the YAML config file and
the raw metadata dictionary.

Raises
------
Expand All @@ -396,7 +413,9 @@ def initialize_report(self, config: dict) -> tuple[r.Report, dict]:
report.sections.append(section)

self.logger.info(
f"Report '{report.title}' initialized with {len(report.sections)} sections."
"Report '%s' initialized with %d sections.",
report.title,
len(report.sections),
)
return report, config

Expand Down Expand Up @@ -472,7 +491,8 @@ def _create_component(self, component_data: dict) -> r.Component:
Returns
-------
Component
A Component object (Plot, DataFrame, or Markdown) populated with the provided metadata.
A Component object (Plot, DataFrame, or Markdown) populated with the
provided metadata.
"""
# Determine the component type
component_type = assert_enum_value(
Expand Down Expand Up @@ -620,8 +640,10 @@ def _create_apicall_component(self, component_data: dict) -> r.APICall:
try:
parsed_body = json.loads(request_body)
except json.JSONDecodeError as e:
self.logger.error(f"Failed to parse request_body JSON: {e}")
raise ValueError(f"Invalid JSON in request_body: {e}")
self.logger.error(
"Failed to parse request_body JSON: %s", e, exc_info=True
)
raise ValueError("Invalid JSON in request_body.") from e

return r.APICall(
title=component_data["title"],
Expand Down
11 changes: 11 additions & 0 deletions src/vuegen/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""Constants for the Vuegen project."""

GITHUB_ORG_URL = "https://github.com/Multiomics-Analytics-Group"
ORG = "Multiomics Network Analytics Group (MoNA)"
GITHUB_ORG_URL_BRACKETS = "{https://github.com/Multiomics-Analytics-Group}"
REPO_URL = "https://github.com/Multiomics-Analytics-Group/vuegen"
LOGO_URL = (
"https://raw.githubusercontent.com/Multiomics-Analytics-Group/"
"vuegen/main/docs/images/vuegen_logo.svg"
)
TIMEOUT: int = 60
Loading