diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ffb858d..4ab9277 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -23,7 +23,7 @@ jobs: python-version: "3.11" environment-file: environment.yml activate-environment: plotlymol - auto-activate: plotlymol + auto-activate: false miniforge-version: latest conda-solver: libmamba @@ -45,7 +45,7 @@ jobs: python-version: "3.11" environment-file: environment.yml activate-environment: plotlymol - auto-activate: plotlymol + auto-activate: false miniforge-version: latest conda-solver: libmamba diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..d7044c0 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,61 @@ +name: Publish to PyPI + +on: + push: + tags: + - "v*.*.*" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Build distribution + run: | + pip install build + python -m build + + - name: Check distribution metadata + run: | + pip install twine + twine check dist/* + + - uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ + + publish-testpypi: + needs: build + runs-on: ubuntu-latest + environment: testpypi + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + + - uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + + publish-pypi: + needs: publish-testpypi + runs-on: ubuntu-latest + environment: pypi + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + + - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 58e771e..6a60fb4 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -27,7 +27,7 @@ jobs: python-version: "3.11" environment-file: environment.yml activate-environment: plotlymol - auto-activate: plotlymol + auto-activate: false miniforge-version: latest conda-solver: libmamba @@ -70,7 +70,7 @@ jobs: python-version: "3.11" environment-file: environment.yml activate-environment: plotlymol - auto-activate: plotlymol + auto-activate: false miniforge-version: latest conda-solver: libmamba diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7d59e42..07c44cd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,7 @@ jobs: python-version: ${{ matrix.python-version }} environment-file: environment.yml activate-environment: plotlymol - auto-activate: plotlymol + auto-activate: false miniforge-version: latest conda-solver: libmamba @@ -46,9 +46,9 @@ jobs: - name: Upload coverage to Codecov if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11' - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: - file: ./coverage.xml + files: ./coverage.xml flags: unittests name: codecov-umbrella fail_ci_if_error: false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2a58b23..6a03ad2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,6 +9,7 @@ repos: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml + args: [--unsafe] - id: check-added-large-files - id: check-merge-conflict - id: debug-statements diff --git a/CHANGELOG.md b/CHANGELOG.md index 83ed112..62b562e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.2.0] - 2026-04-04 + ### Added - **Vibrational Mode Visualization** - Complete system for visualizing molecular vibrations from quantum chemistry calculations - Three file format parsers: Gaussian (.log), ORCA (.out), Molden (.molden) with auto-detection @@ -14,26 +16,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Static displacement arrows using Plotly Cone traces - Animated vibrations with interactive controls (play/pause, frame slider) - Heatmap coloring by displacement magnitude - - New `vibrations.py` module (~1000 lines) with comprehensive dataclasses and functions - - Streamlit "📊 Vibration Settings" section with file upload and interactive controls + - New `vibrations.py` module with comprehensive dataclasses and functions + - Streamlit "Vibration Settings" section with file upload and interactive controls - 21 new tests achieving ~95% coverage of vibration module - Test fixtures for all three file formats (water molecule examples) - Exported vibration functions in `__init__.py` for public API access -- Comprehensive vibration documentation in README with code examples - Symbol-to-atomic-number mapping (`symbol_to_number`) in `atomProperties.py` +- Conda environment (`environment.yml`) replacing venv-based setup +- Security CI workflow: `pip-audit` dependency scanning + CodeQL static analysis +- Dependabot configuration for automated dependency updates +- Branch protection rules (required status checks, no force-push) +- PyPI publishing checklist (`docs/PYPI_PUBLISHING.md`) ### Changed -- Enhanced Streamlit app with vibration file uploader and parameter controls -- Updated README with vibration visualization examples and available parsers + +- Aromatic bond rendering now uses ring-center geometry for correct dashed bond offset direction +- Displacement arrows auto-scaled relative to molecular size for consistent visibility +- Animation caching replaced `@st.cache_data` with session-state caching and live progress bar +- Longer dashes (75% vs 60%) for aromatic bond rendering +- Updated README installation instructions for conda workflow - Expanded test suite from 26 to 47 tests -- Updated CLAUDE.md with vibration module documentation and architecture details - -### Previous Changes -- Expanded README with badges, features list, quick start, orbital example, and GUI instructions. -- Added this changelog. -- Applied Black formatting and Ruff auto-fixes across plotlymol3d and tests. -- Switched to a src/ layout and moved demos into examples/. -- Consolidated dev and runtime dependencies into a single requirements.txt. +- Bumped `requires-python` from `>=3.8` to `>=3.9` +- Fixed repo URLs in `pyproject.toml` (now correctly point to NCCU-Schultz-Lab org) ## [0.1.0] - 2026-01-31 diff --git a/docs/assets/logo.svg b/docs/assets/logo.svg new file mode 100644 index 0000000..66a284b --- /dev/null +++ b/docs/assets/logo.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + plotlyMol + + + + + 3D VISUALIZATION + + diff --git a/mkdocs.yml b/mkdocs.yml index 55cfa95..1d6c96d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -37,8 +37,8 @@ theme: - content.code.annotate icon: repo: fontawesome/brands/github - logo: assets/logo.png - favicon: assets/favicon.png + logo: assets/logo.svg + favicon: assets/logo.svg extra_css: - stylesheets/extra.css diff --git a/pyproject.toml b/pyproject.toml index 0d0d668..c0e4653 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plotlymol" -version = "0.1.0" +version = "0.2.0" description = "A package to create interactive molecular visualizations using Plotly" readme = "README.md" authors = [ @@ -12,7 +12,8 @@ authors = [ {name = "Benjamin Lear"} ] license = {text = "MIT"} -requires-python = ">=3.8" +requires-python = ">=3.9" +keywords = ["chemistry", "molecular visualization", "plotly", "rdkit", "3d", "cheminformatics", "quantum chemistry", "vibrational modes"] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Science/Research", @@ -20,7 +21,6 @@ classifiers = [ "Topic :: Scientific/Engineering :: Visualization", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -37,17 +37,21 @@ dependencies = [ dev = [ "pytest>=7.0.0", "pytest-cov>=4.0.0", - "black>=23.0.0", + "black>=24.3.0", "ruff>=0.1.0", "flake8>=6.0.0", "mypy>=1.0.0", "pre-commit>=3.0.0", ] +gui = [ + "streamlit>=1.30.0", +] [project.urls] -Homepage = "https://github.com/jonathanschultzNU/plotlyMol" -Repository = "https://github.com/jonathanschultzNU/plotlyMol" -Issues = "https://github.com/jonathanschultzNU/plotlyMol/issues" +Homepage = "https://github.com/NCCU-Schultz-Lab/plotlyMol" +Repository = "https://github.com/NCCU-Schultz-Lab/plotlyMol" +Issues = "https://github.com/NCCU-Schultz-Lab/plotlyMol/issues" +Documentation = "https://nccu-schultz-lab.github.io/plotlyMol" [tool.setuptools] packages = ["plotlymol3d"] diff --git a/src/plotlymol3d/app.py b/src/plotlymol3d/app.py index 8ba39b1..1eedba5 100644 --- a/src/plotlymol3d/app.py +++ b/src/plotlymol3d/app.py @@ -942,7 +942,7 @@ def set_random_smiles(): st.sidebar.markdown("---") st.sidebar.caption( - "plotlyMol3D v0.1.0 | [GitHub](https://github.com/jonathanschultzNU/plotlyMol)" + "plotlyMol3D v0.2.0 | [GitHub](https://github.com/NCCU-Schultz-Lab/plotlyMol)" )