From 43882f1f850174a3c1baa17b7408ca2bc70ab8a4 Mon Sep 17 00:00:00 2001 From: Jorge Miguel Silva Date: Thu, 14 Aug 2025 16:02:58 +0100 Subject: [PATCH 1/4] Release 1.2.1: packaging metadata improvements for PyPI (README content-type, authors, classifiers, dependencies, URLs) --- CHANGELOG.md | 7 +++++++ pyproject.toml | 45 +++++++++++++++++++++++++++++++++++++++-- src/phenoqc/__init__.py | 2 +- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0b3585..0f0025c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ +## [1.2.1] - 2025-08-14 +- Packaging: enrich pyproject metadata (authors, classifiers, dependencies, URLs) and set README content-type for PyPI + ## [1.2.0] - 2025-08-14 + - GUI: strategy-agnostic imputation panel (config-driven; per-column overrides; generic tuning) - GUI: fix quality metrics picker defaults when config uses dict-style metrics - Reporting: include categorical PSI/Cramér's V in bias warning header and per-row triggers @@ -6,12 +10,14 @@ - Fix: Python 3.9 compatibility in GUI typing; minor tuning UI improvements ## [1.1.1] - 2025-01-13 + - feat: add class distribution bar chart to PDF and Markdown reports - feat: persist per-file *_qc_summary.json with quality_scores, imputation, class_distribution - fix: Python 3.9 typing compatibility in ImputationEngine (avoid PEP 604 unions) - chore: docs and scripts updated to assert and document new artifact ## [1.1.0] - 2025-01-13 + - feat: Optional class-distribution summary (label-aware) - CLI: `--label-column`, `--imbalance-threshold` - GUI: label column selector and threshold input @@ -23,6 +29,7 @@ - PDF/MD: Imputation Settings and Tuning Summary sections - fix: Redundancy metric deduplication (prefer identical over correlation) - test: Added unit tests for class distribution, imputation params, tuning skeleton, and config load + # Changelog All notable changes to PhenoQC will be documented in this file. diff --git a/pyproject.toml b/pyproject.toml index 41e36c9..34c7170 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,10 +4,51 @@ build-backend = "setuptools.build_meta" [project] name = "phenoqc" -version = "1.2.0" +version = "1.2.1" requires-python = ">=3.9" description = "Phenotypic Data Quality Control Toolkit for Genomic Data Infrastructure (GDI)" -readme = "README.md" +readme = { file = "README.md", content-type = "text/markdown" } +license = { file = "LICENSE" } +authors = [ + { name = "Jorge Miguel Ferreira da Silva" } +] +classifiers = [ + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering :: Bio-Informatics", +] +dependencies = [ + "pandas", + "jsonschema", + "requests", + "plotly", + "reportlab", + "streamlit", + "pyyaml", + "kaleido>=0.1.0", + "tqdm", + "Pillow", + "scikit-learn", + "fancyimpute", + "fastjsonschema", + "pronto", + "psutil", + "rapidfuzz", + "streamlit-aggrid", + "ucimlrepo", +] + +[project.optional-dependencies] +test = ["pytest"] + +[project.urls] +Homepage = "https://github.com/jorgeMFS/PhenoQC" +Repository = "https://github.com/jorgeMFS/PhenoQC.git" +Documentation = "https://phenoqc.readthedocs.io/en/latest/" +Issues = "https://github.com/jorgeMFS/PhenoQC/issues" [project.scripts] phenoqc = "phenoqc.cli:main" diff --git a/src/phenoqc/__init__.py b/src/phenoqc/__init__.py index c1afe52..d8c9955 100644 --- a/src/phenoqc/__init__.py +++ b/src/phenoqc/__init__.py @@ -1,2 +1,2 @@ -__version__ = "1.2.0" +__version__ = "1.2.1" From ca2bcec4a3deb3b5dcaea0876f7d5e5101b7311e Mon Sep 17 00:00:00 2001 From: Jorge Miguel Silva Date: Thu, 14 Aug 2025 17:15:08 +0100 Subject: [PATCH 2/4] Streamlit Cloud: add streamlit_app.py entrypoint, docs note, ensure watchdog in requirements --- README.md | 4 ++++ requirements.txt | 1 + streamlit_app.py | 30 ++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 streamlit_app.py diff --git a/README.md b/README.md index 88ae7a8..e6ee471 100644 --- a/README.md +++ b/README.md @@ -210,7 +210,11 @@ imputation: Launch the Streamlit interface: ```bash +# Local python run_gui.py + +# Streamlit Community Cloud +# In the deploy UI, set the entrypoint to `streamlit_app.py` ``` Workflow: diff --git a/requirements.txt b/requirements.txt index b293214..813d9df 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,3 +17,4 @@ psutil rapidfuzz streamlit-aggrid ucimlrepo +watchdog diff --git a/streamlit_app.py b/streamlit_app.py new file mode 100644 index 0000000..d75a692 --- /dev/null +++ b/streamlit_app.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 + +""" +Streamlit entrypoint for Streamlit Community Cloud. + +This module imports and runs the PhenoQC GUI without spawning a subprocess. +It adjusts sys.path so that `src/` is importable when deployed. +""" + +import os +import sys + + +def main() -> None: + # Ensure `src/` is importable when running on Streamlit Cloud + project_root = os.path.dirname(os.path.abspath(__file__)) + src_path = os.path.join(project_root, "src") + if src_path not in sys.path: + sys.path.insert(0, src_path) + + # Import and run the GUI main + from phenoqc.gui import main as gui_main + + gui_main() + + +if __name__ == "__main__": + main() + + From 6e07614bf3aaccd845f9119a22a621f012c92e42 Mon Sep 17 00:00:00 2001 From: Jorge Miguel Silva Date: Thu, 14 Aug 2025 17:22:46 +0100 Subject: [PATCH 3/4] Added Dev Container Folder --- .devcontainer/devcontainer.json | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..5cfe579 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,33 @@ +{ + "name": "Python 3", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye", + "customizations": { + "codespaces": { + "openFiles": [ + "README.md", + "streamlit_app.py" + ] + }, + "vscode": { + "settings": {}, + "extensions": [ + "ms-python.python", + "ms-python.vscode-pylance" + ] + } + }, + "updateContentCommand": "[ -f packages.txt ] && sudo apt update && sudo apt upgrade -y && sudo xargs apt install -y Date: Thu, 14 Aug 2025 17:36:46 +0100 Subject: [PATCH 4/4] GUI: sanitize protected_columns defaults to be subset of available columns (fix Streamlit Cloud multiselect error) --- src/phenoqc/gui/gui.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/phenoqc/gui/gui.py b/src/phenoqc/gui/gui.py index 0a9734b..1b24970 100644 --- a/src/phenoqc/gui/gui.py +++ b/src/phenoqc/gui/gui.py @@ -942,8 +942,15 @@ def _render_params(spec: dict, initial: Optional[dict] = None) -> dict: # Protected columns st.subheader("Protected columns (excluded from imputation/tuning)") protected_defaults = st.session_state['config'].get('protected_columns', []) or [] - protected_selected = st.multiselect("Select protected columns", options=all_columns, default=protected_defaults, - help="These columns are excluded from the imputation feature matrix and tuning.") + # Streamlit requires defaults to be a subset of options; sanitize to avoid errors when + # config contains columns not present in the current dataset (e.g., on first load). + safe_protected_defaults = [c for c in protected_defaults if c in (all_columns or [])] + protected_selected = st.multiselect( + "Select protected columns", + options=all_columns, + default=safe_protected_defaults, + help="These columns are excluded from the imputation feature matrix and tuning.", + ) st.session_state['config']['protected_columns'] = protected_selected # Redundancy metric settings