From 998a81d66d00f3fe270ea5d505cc992b2e9e5a21 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 12:01:13 +0100 Subject: [PATCH 01/33] Updated pre-commit hooks --- .pre-commit-config.yaml | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index af67085..e99afec 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,15 +1,26 @@ +--- repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 # Use the latest stable version - hooks: - - id: check-added-large-files # Prevent giant files from being committed. - args: ["--maxkb=1000"] - - id: check-merge-conflict # Check for files that contain merge conflict strings. - - id: check-toml # Attempts to load all TOML files to verify syntax. - - id: check-yaml # Attempts to load all yaml files to verify syntax. - args: ["--unsafe"] - + rev: v6.0.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + - id: check-added-large-files # Prevent giant files from being committed. + args: [--maxkb=500] + - id: check-merge-conflict # Check for files that contain merge conflict strings. - repo: https://github.com/kynan/nbstripout - rev: 0.8.1 + rev: 0.8.2 + hooks: + - id: nbstripout # strip jupyter noteook output + - repo: https://github.com/psf/black + rev: 25.12.0 + hooks: + - id: black + # args: [--line-length=88] + # language_version: python3.12 + - repo: https://github.com/pycqa/isort + rev: 7.0.0 hooks: - - id: nbstripout # remove jupyter notebook cell output + - id: isort + name: isort (python) From 908180b8aee63dbe182de2a4d8fba96c4fd838b0 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 12:03:48 +0100 Subject: [PATCH 02/33] Updated pre commit hooks --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e99afec..ea8483f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,11 +10,11 @@ repos: args: [--maxkb=500] - id: check-merge-conflict # Check for files that contain merge conflict strings. - repo: https://github.com/kynan/nbstripout - rev: 0.8.2 + rev: 0.9.0 hooks: - id: nbstripout # strip jupyter noteook output - repo: https://github.com/psf/black - rev: 25.12.0 + rev: 26.1.0 hooks: - id: black # args: [--line-length=88] From a4dca0b7ae76be322fa906f84f119bbd646a837f Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 12:04:59 +0100 Subject: [PATCH 03/33] isort before black --- .pre-commit-config.yaml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ea8483f..33e477f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,14 +13,12 @@ repos: rev: 0.9.0 hooks: - id: nbstripout # strip jupyter noteook output - - repo: https://github.com/psf/black - rev: 26.1.0 - hooks: - - id: black - # args: [--line-length=88] - # language_version: python3.12 - repo: https://github.com/pycqa/isort rev: 7.0.0 hooks: - id: isort name: isort (python) + - repo: https://github.com/psf/black + rev: 26.1.0 + hooks: + - id: black From cffa0821b1c4380c08a9c10f552af53e77cf2a4c Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 12:06:10 +0100 Subject: [PATCH 04/33] Updated python versions --- pyproject.toml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ee0af26..1a57f17 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,16 +11,12 @@ readme = "README.md" keywords = [ "python" ] license = { file = "LICENSE.txt" } authors = [ { name = "Max" } ] -requires-python = ">=3.8" +requires-python = ">=3.10" classifiers = [ "Development Status :: 3 - Alpha", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", ] dependencies = [ "numpy", @@ -53,4 +49,3 @@ where = [ "src" ] [tool.isort] profile = "black" - From 80e9ebb1eead46632d1f24446bcc3a22d12f793a Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 12:13:01 +0100 Subject: [PATCH 05/33] Moved tests into the src --- {tests => src/app/tests}/unit/__init__.py | 0 {tests => src/app/tests}/unit/test_app.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {tests => src/app/tests}/unit/__init__.py (100%) rename {tests => src/app/tests}/unit/test_app.py (100%) diff --git a/tests/unit/__init__.py b/src/app/tests/unit/__init__.py similarity index 100% rename from tests/unit/__init__.py rename to src/app/tests/unit/__init__.py diff --git a/tests/unit/test_app.py b/src/app/tests/unit/test_app.py similarity index 100% rename from tests/unit/test_app.py rename to src/app/tests/unit/test_app.py From 23e2f8db1cac78accd2726f1229ab41fd4cef18f Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 12:14:25 +0100 Subject: [PATCH 06/33] Added script for setting up project --- setup_project.sh | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 setup_project.sh diff --git a/setup_project.sh b/setup_project.sh new file mode 100644 index 0000000..5a26113 --- /dev/null +++ b/setup_project.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ $# -ne 1 ]]; then + echo "Usage: $0 " + exit 1 +fi + +APPNAME="$1" +APPNAME_UNDERSCORE="${APPNAME//-/_}" + +# 1. Find and replace "testproject" with app name +grep -rl "testproject" . | while IFS= read -r file; do + LC_ALL=C sed -i.bak "s/testproject/${APPNAME}/g" "$file" + rm -f "${file}.bak" +done + +# 2. Move src/app to src/ +if [[ -d "src/app" ]]; then + mv src/app "src/${APPNAME_UNDERSCORE}" +else + echo "Error: src/app does not exist" + exit 1 +fi + +echo "Done:" +echo " Replaced 'testproject' → '${APPNAME}'" +echo " Moved src/app → src/${APPNAME_UNDERSCORE}" From 22db63e61b67aaf50a58026c8c9546a753256c03 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 12:18:56 +0100 Subject: [PATCH 07/33] Rename the import --- setup_project.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) mode change 100644 => 100755 setup_project.sh diff --git a/setup_project.sh b/setup_project.sh old mode 100644 new mode 100755 index 5a26113..380bdd6 --- a/setup_project.sh +++ b/setup_project.sh @@ -23,6 +23,17 @@ else exit 1 fi +# 3. Replace import in src/**/*.py +# from app.main import main -> from .main import main + +find src -type f -name "*.py" -print0 | while IFS= read -r -d '' file; do + LC_ALL=C sed -i.bak \ + "s/from app\.main import main/from ${APPNAME_UNDERSCORE}.main import main/g" \ + "$file" + rm -f "${file}.bak" +done + + echo "Done:" echo " Replaced 'testproject' → '${APPNAME}'" echo " Moved src/app → src/${APPNAME_UNDERSCORE}" From fc469d9ba2ec77c4bcab27cccdd3bb8b8485f8a8 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 12:19:55 +0100 Subject: [PATCH 08/33] Updated prints --- setup_project.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup_project.sh b/setup_project.sh index 380bdd6..436ca50 100755 --- a/setup_project.sh +++ b/setup_project.sh @@ -37,3 +37,4 @@ done echo "Done:" echo " Replaced 'testproject' → '${APPNAME}'" echo " Moved src/app → src/${APPNAME_UNDERSCORE}" +echo " Replaced import statements in src/**/*.py" From 7c92571b0389a6a42b83bc37573ec709ee189255 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 12:27:53 +0100 Subject: [PATCH 09/33] Added more deps --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 1a57f17..b27f9e9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,10 +35,13 @@ optional-dependencies.docs = [ "nbconvert", "nbsphinx", "jupyterlab", + "linkify-it-py", "pre-commit", "pyproject-fmt", "sphinx", "sphinx-book-theme", + "sphinxcontrib-mermaid", + "sphinx-design", ] optional-dependencies.test = [ "coverage", "pytest" ] urls."Source" = "https://github.com/max-models/template-python" From 98fc575f228080785f9e0f8b0a560fb2705f739c Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 12:30:36 +0100 Subject: [PATCH 10/33] Added _static --- docs/_static/custom.css | 93 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 docs/_static/custom.css diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 0000000..a9aa047 --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1,93 @@ +/* Improved toctree styling */ + +/* Main page toctree container */ +.toctree-wrapper { + margin: 2rem 0; +} + +/* Toctree list styling */ +.toctree-wrapper ul { + padding-left: 0; + list-style: none; +} + +/* Toctree list items */ +.toctree-wrapper li { + margin: 0.4rem 0; + padding: 0.6rem 1rem; + border-bottom: 1.5px solid #c5d1e0; + border-left: 3px solid transparent; + transition: all 0.2s ease; +} + +.toctree-wrapper li:hover { + border-left-color: #4f46e5; + background: rgba(79, 70, 229, 0.03); +} + +.toctree-wrapper li:last-child { + border-bottom: 1.5px solid #c5d1e0; +} + +/* Toctree links */ +.toctree-wrapper a.reference { + font-size: 1.1rem; + font-weight: 500; + color: #1a365d; + text-decoration: none; + display: inline-block; + transition: all 0.2s ease; + padding: 0.25rem 0; +} + +.toctree-wrapper a.reference:hover { + color: #2563eb; + transform: translateX(5px); +} + +/* Nested toctree items */ +.toctree-wrapper ul ul { + padding-left: 1.5rem; + margin-top: 0.3rem; +} + +.toctree-wrapper ul ul li { + margin: 0.25rem 0; + padding: 0.4rem 0.8rem; + border-bottom: 1px solid #dce4f0; + border-left: 2px solid transparent; +} + +.toctree-wrapper ul ul li:hover { + border-left-color: #6366f1; + background: rgba(99, 102, 241, 0.03); +} + +.toctree-wrapper ul ul a.reference { + font-size: 1rem; + font-weight: 400; + color: #4a5568; +} + +.toctree-wrapper ul ul a.reference:hover { + color: #4f46e5; +} + +/* Toctree caption */ +.toctree-wrapper p.caption { + font-size: 1.3rem; + font-weight: 600; + color: #1e3a5f; + margin-bottom: 1rem; + padding-bottom: 0.5rem; + border-bottom: 3px solid #4f46e5; +} + +/* Improve spacing on main page */ +div.section > .toctree-wrapper { + background: linear-gradient(135deg, #f0f4f8 0%, #e8eef5 100%); + padding: 1.5rem; + border-radius: 12px; + box-shadow: 0 4px 6px rgba(79, 70, 229, 0.08); + border: 1px solid #dce4f0; +} From 4787fc55d502d43141144e050ce1cbf26a7f2fba Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 12:41:13 +0100 Subject: [PATCH 11/33] Moved custom.css --- docs/{ => source}/_static/custom.css | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{ => source}/_static/custom.css (100%) diff --git a/docs/_static/custom.css b/docs/source/_static/custom.css similarity index 100% rename from docs/_static/custom.css rename to docs/source/_static/custom.css From c9d68e8ec9172d30d86dcd2210f36df03ab260b6 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 12:53:19 +0100 Subject: [PATCH 12/33] Rewrote the docs a bit --- docs/source/api.md | 6 -- docs/source/api/all_classes.rst | 9 +++ docs/source/api/index.rst | 10 +++ docs/source/conf.py | 88 ++++++++++++--------- docs/source/getting_started.rst | 11 +++ docs/source/guides/install.rst | 30 +++++++ docs/source/guides/quickstart.rst | 6 ++ docs/source/index.md | 11 --- docs/source/index.rst | 14 ++++ docs/source/quickstart.md | 38 --------- docs/source/{tutorials.md => tutorials.rst} | 2 +- 11 files changed, 130 insertions(+), 95 deletions(-) delete mode 100644 docs/source/api.md create mode 100644 docs/source/api/all_classes.rst create mode 100644 docs/source/api/index.rst create mode 100644 docs/source/getting_started.rst create mode 100644 docs/source/guides/install.rst create mode 100644 docs/source/guides/quickstart.rst delete mode 100644 docs/source/index.md create mode 100644 docs/source/index.rst delete mode 100644 docs/source/quickstart.md rename docs/source/{tutorials.md => tutorials.rst} (89%) diff --git a/docs/source/api.md b/docs/source/api.md deleted file mode 100644 index a1c08b6..0000000 --- a/docs/source/api.md +++ /dev/null @@ -1,6 +0,0 @@ -# API - -Description of the API - -```{toctree} -:maxdepth: 1 \ No newline at end of file diff --git a/docs/source/api/all_classes.rst b/docs/source/api/all_classes.rst new file mode 100644 index 0000000..9936e69 --- /dev/null +++ b/docs/source/api/all_classes.rst @@ -0,0 +1,9 @@ +Full Class Index +================ + +All Classes and Functions +-------------------------- + +This page contains the complete API reference for all SAPIC classes and functions. + +.. doxygenindex:: diff --git a/docs/source/api/index.rst b/docs/source/api/index.rst new file mode 100644 index 0000000..6cdd41d --- /dev/null +++ b/docs/source/api/index.rst @@ -0,0 +1,10 @@ +API Reference +============= + +This section contains the automatically generated C++ API reference. + +.. toctree:: + :maxdepth: 1 + :caption: Full API Index + + all_classes diff --git a/docs/source/conf.py b/docs/source/conf.py index 85ee72f..d9c3b85 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -2,26 +2,10 @@ # # For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html - import os -import shutil - - -def copy_tutorials(app): - src = os.path.abspath("../tutorials") - dst = os.path.abspath("source/tutorials") - - # Remove existing target directory if it exists - if os.path.exists(dst): - shutil.rmtree(dst) +import sys - shutil.copytree(src, dst) - - -def setup(app): - app.connect("builder-inited", copy_tutorials) - # app.add_stylesheet("my-styles.css") - app.add_css_file("custom.css") +sys.path.insert(0, os.path.abspath("../src")) # -- Project information ----------------------------------------------------- @@ -32,46 +16,72 @@ def setup(app): author = "Max" # -- General configuration --------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. extensions = [ - "nbsphinx", - "sphinx.ext.mathjax", "sphinx.ext.autodoc", - "myst_parser", # enable Markdown support + "sphinx.ext.autosummary", + "sphinx.ext.viewcode", + "sphinx.ext.napoleon", + "sphinxcontrib.mermaid", + "sphinx_design", + "myst_parser", ] -exclude_patterns = [] +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] -# Recognize both .rst and .md -source_suffix = { - ".rst": "restructuredtext", - ".md": "markdown", -} # -- Options for HTML output ------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -# Activate the theme. +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# html_theme = "sphinx_book_theme" - -html_static_path = ["_static"] -templates_path = ["_templates"] - - -# html_sidebars = {"**": []} - html_theme_options = { "repository_branch": "devel", - "show_toc_level": 3, + "show_toc_level": 2, "secondary_sidebar_items": ["page-toc"], + "use_sidenotes": True, + "home_page_in_toc": True, + "collapse_navigation": False, + "navigation_depth": 2, "icon_links": [ { "name": "GitHub", - "url": "https://github.com/max-models/template-python", + "url": "https://github.com/max-models/template-projects/", "icon": "fab fa-github", "type": "fontawesome", }, + { + "name": "⭐ Star us!", + "url": "https://github.com/max-models/template-projects/", + "icon": "fas fa-star", + "type": "fontawesome", + }, ], } + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +breathe_separate_member_pages = False +html_theme = "sphinx_book_theme" +html_static_path = ["_static"] +html_css_files = ["custom.css"] + +autosummary_generate = True + +autodoc_default_options = { + "members": True, + "undoc-members": False, + "show-inheritance": True, +} diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst new file mode 100644 index 0000000..4890f2d --- /dev/null +++ b/docs/source/getting_started.rst @@ -0,0 +1,11 @@ +Getting Started +=============== + +Learn how to install and use `template-python`. + +.. toctree:: + :maxdepth: 1 + + guides/install + guides/quickstart + tutorials diff --git a/docs/source/guides/install.rst b/docs/source/guides/install.rst new file mode 100644 index 0000000..04922ba --- /dev/null +++ b/docs/source/guides/install.rst @@ -0,0 +1,30 @@ +Installation +============ + +Create and activate python environment:: + + python -m venv env + source env/bin/activate + pip install --upgrade pip + +Install the code and requirements with pip:: + + pip install -e . + +Run the code with:: + + template-python + + +Build docs +========== + +:: + + make html + cd ../ + open docs/_build/html/index.html + + +.. toctree:: + :maxdepth: 1 diff --git a/docs/source/guides/quickstart.rst b/docs/source/guides/quickstart.rst new file mode 100644 index 0000000..d219ff4 --- /dev/null +++ b/docs/source/guides/quickstart.rst @@ -0,0 +1,6 @@ +# Quickstart + +First, ensure that `template-python` is installed on your system. + +```{toctree} +:maxdepth: 1 diff --git a/docs/source/index.md b/docs/source/index.md deleted file mode 100644 index d082474..0000000 --- a/docs/source/index.md +++ /dev/null @@ -1,11 +0,0 @@ -# Welcome - -Write the documentation of your python package here - -```{toctree} -:maxdepth: 2 -:caption: Contents - -quickstart.md -tutorials.md -api.md diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..4ed8623 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,14 @@ +template-python Documentation +============================= + +Write the documentation of your python package here + +.. toctree:: + :maxdepth: 1 + :caption: Documentation + + getting_started + tutorials + code_overview + development + api/index diff --git a/docs/source/quickstart.md b/docs/source/quickstart.md deleted file mode 100644 index a2d6ec8..0000000 --- a/docs/source/quickstart.md +++ /dev/null @@ -1,38 +0,0 @@ -# Quickstart - -Clone the repo - -``` -git clone ... -``` - -Create and activate python environment - -``` -python -m venv env -source env/bin/activate -pip install --upgrade pip -``` - -Install the code and requirements with pip - -``` -pip install -e . -``` - -Run the code with - -``` -template-python -``` - -# Build docs - -``` -make html -cd ../ -open docs/_build/html/index.html -``` - -```{toctree} -:maxdepth: 1 \ No newline at end of file diff --git a/docs/source/tutorials.md b/docs/source/tutorials.rst similarity index 89% rename from docs/source/tutorials.md rename to docs/source/tutorials.rst index 84e10de..a6b12f4 100644 --- a/docs/source/tutorials.md +++ b/docs/source/tutorials.rst @@ -6,4 +6,4 @@ Here are a few tutorials to help you get started. :maxdepth: 1 :glob: -tutorials/* \ No newline at end of file +tutorials/* From a9f08b5b0219471b5bb35d8ef62f2e7a0645d1c8 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 13:05:36 +0100 Subject: [PATCH 13/33] Updated the docs --- docs/source/api/all_classes.rst | 9 --------- docs/source/api/index.rst | 13 ++++++++----- docs/source/conf.py | 2 +- docs/source/guides/quickstart.rst | 18 ++++++++++++++---- docs/source/index.rst | 5 +---- docs/source/tutorials.rst | 10 +++++----- 6 files changed, 29 insertions(+), 28 deletions(-) delete mode 100644 docs/source/api/all_classes.rst diff --git a/docs/source/api/all_classes.rst b/docs/source/api/all_classes.rst deleted file mode 100644 index 9936e69..0000000 --- a/docs/source/api/all_classes.rst +++ /dev/null @@ -1,9 +0,0 @@ -Full Class Index -================ - -All Classes and Functions --------------------------- - -This page contains the complete API reference for all SAPIC classes and functions. - -.. doxygenindex:: diff --git a/docs/source/api/index.rst b/docs/source/api/index.rst index 6cdd41d..d1bd8af 100644 --- a/docs/source/api/index.rst +++ b/docs/source/api/index.rst @@ -1,10 +1,13 @@ API Reference ============= -This section contains the automatically generated C++ API reference. +This section contains the automatically generated Python API reference. -.. toctree:: - :maxdepth: 1 - :caption: Full API Index +Modules +------- - all_classes +.. autosummary:: + :toctree: _autosummary + :recursive: + + app diff --git a/docs/source/conf.py b/docs/source/conf.py index d9c3b85..86d1fd8 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -27,7 +27,7 @@ "sphinx.ext.napoleon", "sphinxcontrib.mermaid", "sphinx_design", - "myst_parser", + "nbsphinx", ] # Add any paths that contain templates here, relative to this directory. diff --git a/docs/source/guides/quickstart.rst b/docs/source/guides/quickstart.rst index d219ff4..4bea978 100644 --- a/docs/source/guides/quickstart.rst +++ b/docs/source/guides/quickstart.rst @@ -1,6 +1,16 @@ -# Quickstart +Quickstart +========== -First, ensure that `template-python` is installed on your system. +First, ensure that ``template-python`` is installed on your system. -```{toctree} -:maxdepth: 1 +Basic Usage +----------- + +After installation, you can run the application with:: + + template-python + +For more details, see the :doc:`install` guide. + +.. toctree:: + :maxdepth: 1 diff --git a/docs/source/index.rst b/docs/source/index.rst index 4ed8623..85109c7 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,14 +1,11 @@ template-python Documentation ============================= -Write the documentation of your python package here +Write the documentation of your python package here. .. toctree:: :maxdepth: 1 :caption: Documentation getting_started - tutorials - code_overview - development api/index diff --git a/docs/source/tutorials.rst b/docs/source/tutorials.rst index a6b12f4..4848767 100644 --- a/docs/source/tutorials.rst +++ b/docs/source/tutorials.rst @@ -1,9 +1,9 @@ -# Tutorials +Tutorials +========= Here are a few tutorials to help you get started. -```{toctree} -:maxdepth: 1 -:glob: +.. toctree:: + :maxdepth: 1 -tutorials/* + tutorials/example_tutorial From d4437e7bbad5017fed6cf9a0835ae627c8f44c1f Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 13:06:31 +0100 Subject: [PATCH 14/33] Autosummary to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index eaf73dd..6548c34 100644 --- a/.gitignore +++ b/.gitignore @@ -172,3 +172,4 @@ cython_debug/ # Unit test output junit/ +docs/source/api/_autosummary/ From e54c1ea5f3f87592a8ba67d1180622224fdcca16 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 13:11:12 +0100 Subject: [PATCH 15/33] Added ruff to pre-commit --- .github/workflows/static_analysis.yml | 77 +++++++-------------------- .pre-commit-config.yaml | 6 +++ 2 files changed, 24 insertions(+), 59 deletions(-) diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index 61b3cb6..dd976df 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -15,42 +15,32 @@ defaults: shell: bash jobs: - cloc: + pre-commit: runs-on: ubuntu-latest steps: - name: Checkout the code uses: actions/checkout@v4 - - name: Download and run cloc - run: | - curl -s https://raw.githubusercontent.com/AlDanial/cloc/master/cloc > cloc - chmod +x cloc - ./cloc --version - ./cloc $(git ls-files) - - black: - runs-on: ubuntu-latest - steps: - - name: Checkout the code - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' - - name: Code formatting with black - run: | - pip install black "black[jupyter]" - black --check src/ - black --check tutorials/ + - name: Run pre-commit + uses: pre-commit/action@v3.0.1 - isort: + cloc: runs-on: ubuntu-latest steps: - name: Checkout the code uses: actions/checkout@v4 - - name: Code formatting with isort + - name: Download and run cloc run: | - pip install isort - isort --check src/ - isort --check tutorials/ + curl -s https://raw.githubusercontent.com/AlDanial/cloc/master/cloc > cloc + chmod +x cloc + ./cloc --version + ./cloc $(git ls-files) mypy: runs-on: ubuntu-latest @@ -59,43 +49,12 @@ jobs: - name: Checkout the code uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + - name: Type checking with mypy run: | pip install mypy mypy src/ || true - - prospector: - runs-on: ubuntu-latest - continue-on-error: true - steps: - - name: Checkout the code - uses: actions/checkout@v4 - - - name: Code analysis with prospector - run: | - pip install prospector - prospector src/ || true - - ruff: - runs-on: ubuntu-latest - continue-on-error: true - steps: - - name: Checkout the code - uses: actions/checkout@v4 - - - name: Linting with ruff - run: | - pip install ruff - ruff check src/ || true - - pylint: - runs-on: ubuntu-latest - continue-on-error: true - steps: - - name: Checkout the code - uses: actions/checkout@v4 - - - name: Linting with pylint - run: | - pip install pylint - pylint src/ || true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 33e477f..b70aead 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,3 +22,9 @@ repos: rev: 26.1.0 hooks: - id: black + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.9.1 + hooks: + - id: ruff + args: [--fix] + - id: ruff-format From 6e514f9b65a67b24713f3ae1d40b1a7d78a904ce Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 13:14:31 +0100 Subject: [PATCH 16/33] Added test_docs_job --- .github/workflows/docs.yml | 2 +- .github/workflows/test_docs.yml | 50 +++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/test_docs.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index c59b8ea..5c9d160 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -2,7 +2,7 @@ name: Deploy docs to GitHub Pages on: push: - branches: ["devel", "main"] # TODO: Set to main only after release + branches: ["devel"] workflow_dispatch: permissions: diff --git a/.github/workflows/test_docs.yml b/.github/workflows/test_docs.yml new file mode 100644 index 0000000..bce688f --- /dev/null +++ b/.github/workflows/test_docs.yml @@ -0,0 +1,50 @@ +name: Test Documentation Build + +on: + push: + branches: + - main + - devel + pull_request: + branches: + - main + - devel + +defaults: + run: + shell: bash + +jobs: + test-docs: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Install pandoc + run: | + sudo apt-get update + sudo apt-get install -y pandoc + + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + pip install ".[docs]" + + - name: Build Sphinx docs + run: | + cd docs + sphinx-build -b html -W --keep-going source build/html + + - name: Upload docs artifact + uses: actions/upload-artifact@v4 + if: always() + with: + name: documentation + path: docs/build/html/ + retention-days: 7 From 911daddc96b598f29afc4d5f5b9aaa7d1effde3b Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 13:17:37 +0100 Subject: [PATCH 17/33] Adde test_docs --- .github/actions/build-docs/action.yml | 40 +++++++++++++++++++ .../workflows/{docs.yml => publish_docs.yml} | 19 +++------ .../{publish.yml => publish_pypi.yml} | 1 - .github/workflows/test_docs.yml | 20 ++-------- 4 files changed, 48 insertions(+), 32 deletions(-) create mode 100644 .github/actions/build-docs/action.yml rename .github/workflows/{docs.yml => publish_docs.yml} (68%) rename .github/workflows/{publish.yml => publish_pypi.yml} (99%) diff --git a/.github/actions/build-docs/action.yml b/.github/actions/build-docs/action.yml new file mode 100644 index 0000000..7795498 --- /dev/null +++ b/.github/actions/build-docs/action.yml @@ -0,0 +1,40 @@ +name: 'Build Documentation' +description: 'Build Sphinx documentation' +inputs: + python-version: + description: 'Python version to use' + required: false + default: '3.10' + treat-warnings-as-errors: + description: 'Treat warnings as errors (-W flag)' + required: false + default: 'false' +runs: + using: 'composite' + steps: + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ inputs.python-version }} + + - name: Install pandoc + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y pandoc + + - name: Install Python dependencies + shell: bash + run: | + python -m pip install --upgrade pip + pip install ".[docs]" + + - name: Build Sphinx docs + shell: bash + run: | + cd docs + if [ "${{ inputs.treat-warnings-as-errors }}" = "true" ]; then + sphinx-build -b html -W --keep-going source build/html + else + sphinx-build -b html source build/html + fi diff --git a/.github/workflows/docs.yml b/.github/workflows/publish_docs.yml similarity index 68% rename from .github/workflows/docs.yml rename to .github/workflows/publish_docs.yml index 5c9d160..553243a 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/publish_docs.yml @@ -25,20 +25,11 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Install pandoc - run: | - sudo apt-get update - sudo apt-get install -y pandoc - - - name: Install Python dependencies - run: | - python -m pip install --upgrade pip - pip install ".[docs]" - - - name: Build Sphinx docs - run: | - cd docs - make html + - name: Build documentation + uses: ./.github/actions/build-docs + with: + python-version: '3.10' + treat-warnings-as-errors: 'false' - name: Setup Pages uses: actions/configure-pages@v5 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish_pypi.yml similarity index 99% rename from .github/workflows/publish.yml rename to .github/workflows/publish_pypi.yml index d91ffc6..6a4ba69 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish_pypi.yml @@ -32,4 +32,3 @@ jobs: # TWINE_USERNAME: __token__ # Use API token # TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} # run: twine upload dist/* - diff --git a/.github/workflows/test_docs.yml b/.github/workflows/test_docs.yml index bce688f..ffe898d 100644 --- a/.github/workflows/test_docs.yml +++ b/.github/workflows/test_docs.yml @@ -21,25 +21,11 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 + - name: Build documentation + uses: ./.github/actions/build-docs with: python-version: '3.10' - - - name: Install pandoc - run: | - sudo apt-get update - sudo apt-get install -y pandoc - - - name: Install Python dependencies - run: | - python -m pip install --upgrade pip - pip install ".[docs]" - - - name: Build Sphinx docs - run: | - cd docs - sphinx-build -b html -W --keep-going source build/html + treat-warnings-as-errors: 'true' - name: Upload docs artifact uses: actions/upload-artifact@v4 From 56d7981a67b7750d64997b84cf373e2193386fc8 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 13:23:35 +0100 Subject: [PATCH 18/33] isort,black --> ruff --- .pre-commit-config.yaml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b70aead..b96501a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,18 +13,9 @@ repos: rev: 0.9.0 hooks: - id: nbstripout # strip jupyter noteook output - - repo: https://github.com/pycqa/isort - rev: 7.0.0 - hooks: - - id: isort - name: isort (python) - - repo: https://github.com/psf/black - rev: 26.1.0 - hooks: - - id: black - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.9.1 hooks: - id: ruff - args: [--fix] + args: [--fix, --select, I] - id: ruff-format From 82a0fff8067ade8bbae1d69a7b0c360119be2765 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 13:26:09 +0100 Subject: [PATCH 19/33] Added rm --- setup_project.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/setup_project.sh b/setup_project.sh index 436ca50..63ab141 100755 --- a/setup_project.sh +++ b/setup_project.sh @@ -38,3 +38,4 @@ echo "Done:" echo " Replaced 'testproject' → '${APPNAME}'" echo " Moved src/app → src/${APPNAME_UNDERSCORE}" echo " Replaced import statements in src/**/*.py" +echo "You can now remove this script with: rm setup_project.sh" From c89a708fb2645d65954183dc7eff4d0750745189 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 13:28:48 +0100 Subject: [PATCH 20/33] Test setup script --- .github/workflows/test_setup_script.yml | 67 +++++++++++++++++++++++++ .github/workflows/testing.yml | 6 +-- 2 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/test_setup_script.yml diff --git a/.github/workflows/test_setup_script.yml b/.github/workflows/test_setup_script.yml new file mode 100644 index 0000000..6422326 --- /dev/null +++ b/.github/workflows/test_setup_script.yml @@ -0,0 +1,67 @@ +name: Test Setup Script + +on: + push: + branches: + - main + - devel + pull_request: + branches: + - main + - devel + +defaults: + run: + shell: bash + +jobs: + test-setup-script: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Run setup script + run: | + bash setup_project.sh my-test-app + + - name: Verify changes + run: | + # Check that src/app was moved to src/my_test_app + if [ ! -d "src/my_test_app" ]; then + echo "Error: src/my_test_app does not exist" + exit 1 + fi + + # Check that src/app no longer exists + if [ -d "src/app" ]; then + echo "Error: src/app still exists" + exit 1 + fi + + # Check that testproject was replaced in pyproject.toml + if grep -q "testproject" pyproject.toml; then + echo "Error: 'testproject' still found in pyproject.toml" + exit 1 + fi + + if ! grep -q "my-test-app" pyproject.toml; then + echo "Error: 'my-test-app' not found in pyproject.toml" + exit 1 + fi + + echo "✓ All checks passed!" + + - name: Install project with new name + run: | + pip install --upgrade pip + pip install -e . + + - name: Test renamed command works + run: | + my-test-app diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index f84e48c..634eac4 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -44,10 +44,6 @@ jobs: pip install --upgrade pip pip install ".[dev]" - - name: Check installation - run: | - template-python - - name: Run tests run: | pytest . @@ -63,4 +59,4 @@ jobs: make clean make html cd .. - ls docs/build/html/index.html \ No newline at end of file + ls docs/build/html/index.html From 9df0568f69fa4d93db85f5b8cf79518f19ddb68c Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 13:30:11 +0100 Subject: [PATCH 21/33] Fixes --- .gitattributes | 2 +- .gitlab-ci.yml | 1 - pytest.ini | 2 +- tutorials/example_tutorial.ipynb | 16 ++++------------ 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/.gitattributes b/.gitattributes index 2f41707..8425c58 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -*.ipynb filter=strip-notebook-output +*.ipynb filter=strip-notebook-output diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7de373c..d0b7c87 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -54,4 +54,3 @@ deploy: stage: deploy script: echo "Define your deployment script!" environment: production - diff --git a/pytest.ini b/pytest.ini index fa4a21d..fcccae1 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,2 +1,2 @@ -[pytest] +[pytest] pythonpath = src diff --git a/tutorials/example_tutorial.ipynb b/tutorials/example_tutorial.ipynb index 4f568bb..da4e6f7 100644 --- a/tutorials/example_tutorial.ipynb +++ b/tutorials/example_tutorial.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "efb79425-958b-412c-afa9-055e27a69baa", + "id": "0", "metadata": {}, "source": [ "# Tutorial 1" @@ -10,18 +10,10 @@ }, { "cell_type": "code", - "execution_count": 1, - "id": "68ad1562-4953-444c-96c7-9026bcc54cc7", + "execution_count": null, + "id": "1", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Example tutorial which will be published in the docs!\n" - ] - } - ], + "outputs": [], "source": [ "print(\"Example tutorial which will be published in the docs!\")" ] From e8062b42f13d228bb9a1c0cd6ce05100cf4c5cc8 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 13:33:22 +0100 Subject: [PATCH 22/33] Renaming --- .github/workflows/{testing.yml => test.yml} | 9 --------- 1 file changed, 9 deletions(-) rename .github/workflows/{testing.yml => test.yml} (85%) diff --git a/.github/workflows/testing.yml b/.github/workflows/test.yml similarity index 85% rename from .github/workflows/testing.yml rename to .github/workflows/test.yml index 634eac4..fbc55a1 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/test.yml @@ -51,12 +51,3 @@ jobs: - name: Test tutorials run: | jupyter nbconvert --to notebook --execute tutorials/*.ipynb --output-dir=/tmp --ExecutePreprocessor.timeout=300 - - - name: Test docs build - run: | - pip install ".[docs]" - cd docs - make clean - make html - cd .. - ls docs/build/html/index.html From 0dba336a8e95f991d400c86bb1e3737d78b92cfc Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 13:35:23 +0100 Subject: [PATCH 23/33] Separate tutorial and pytest --- .github/workflows/test.yml | 26 +++++----------- .github/workflows/test_pytest.yml | 41 +++++++++++++++++++++++++ .github/workflows/test_tutorials.yml | 46 ++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/test_pytest.yml create mode 100644 .github/workflows/test_tutorials.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fbc55a1..42b12d9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Tests +name: Test Pytest on: push: @@ -11,43 +11,31 @@ on: - devel jobs: - build: + pytest: runs-on: ubuntu-latest steps: - # Checkout the repository - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - # Set up Python - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: - python-version: '3.10' # Adjust as needed + python-version: '3.10' - # Cache pip dependencies - name: Cache pip - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }} restore-keys: | ${{ runner.os }}-pip- - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y pandoc - - name: Install project run: | pip install --upgrade pip - pip install ".[dev]" + pip install ".[test]" - name: Run tests run: | pytest . - - - name: Test tutorials - run: | - jupyter nbconvert --to notebook --execute tutorials/*.ipynb --output-dir=/tmp --ExecutePreprocessor.timeout=300 diff --git a/.github/workflows/test_pytest.yml b/.github/workflows/test_pytest.yml new file mode 100644 index 0000000..42b12d9 --- /dev/null +++ b/.github/workflows/test_pytest.yml @@ -0,0 +1,41 @@ +name: Test Pytest + +on: + push: + branches: + - main + - devel + pull_request: + branches: + - main + - devel + +jobs: + pytest: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Cache pip + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install project + run: | + pip install --upgrade pip + pip install ".[test]" + + - name: Run tests + run: | + pytest . diff --git a/.github/workflows/test_tutorials.yml b/.github/workflows/test_tutorials.yml new file mode 100644 index 0000000..599aa81 --- /dev/null +++ b/.github/workflows/test_tutorials.yml @@ -0,0 +1,46 @@ +name: Test Tutorials + +on: + push: + branches: + - main + - devel + pull_request: + branches: + - main + - devel + +jobs: + tutorials: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Cache pip + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y pandoc + + - name: Install project + run: | + pip install --upgrade pip + pip install ".[dev]" + + - name: Execute tutorials + run: | + jupyter nbconvert --to notebook --execute tutorials/*.ipynb --output-dir=/tmp --ExecutePreprocessor.timeout=300 From 821c50157bc21a49d2417a84f20854be5a5413e1 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 14:30:24 +0100 Subject: [PATCH 24/33] Fixed setup_project.sh --- .github/workflows/test_setup_script.yml | 20 +++----------------- setup_project.sh | 15 +++++++++++---- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/.github/workflows/test_setup_script.yml b/.github/workflows/test_setup_script.yml index 6422326..50e455f 100644 --- a/.github/workflows/test_setup_script.yml +++ b/.github/workflows/test_setup_script.yml @@ -44,23 +44,9 @@ jobs: exit 1 fi - # Check that testproject was replaced in pyproject.toml - if grep -q "testproject" pyproject.toml; then - echo "Error: 'testproject' still found in pyproject.toml" - exit 1 - fi - - if ! grep -q "my-test-app" pyproject.toml; then - echo "Error: 'my-test-app' not found in pyproject.toml" - exit 1 - fi - - echo "✓ All checks passed!" - - - name: Install project with new name - run: | - pip install --upgrade pip - pip install -e . + # Check that template-python was replaced in pyproject.toml + if grep -q "template-python" pyproject.toml; then + echo "Error: 'template-python' still found in pyproject.toml" - name: Test renamed command works run: | diff --git a/setup_project.sh b/setup_project.sh index 63ab141..b3a53e1 100755 --- a/setup_project.sh +++ b/setup_project.sh @@ -9,9 +9,15 @@ fi APPNAME="$1" APPNAME_UNDERSCORE="${APPNAME//-/_}" -# 1. Find and replace "testproject" with app name -grep -rl "testproject" . | while IFS= read -r file; do - LC_ALL=C sed -i.bak "s/testproject/${APPNAME}/g" "$file" +# 1. Find and replace "template-python" with app name +grep -rl "template-python" . --exclude-dir=.git --exclude-dir=docs/build | while IFS= read -r file; do + LC_ALL=C sed -i.bak "s/template-python/${APPNAME}/g" "$file" + rm -f "${file}.bak" +done + +# Also replace template_python with appname_underscore +grep -rl "template_python" . --exclude-dir=.git --exclude-dir=docs/build | while IFS= read -r file; do + LC_ALL=C sed -i.bak "s/template_python/${APPNAME_UNDERSCORE}/g" "$file" rm -f "${file}.bak" done @@ -35,7 +41,8 @@ done echo "Done:" -echo " Replaced 'testproject' → '${APPNAME}'" +echo " Replaced 'template-python' → '${APPNAME}'" +echo " Replaced 'template_python' → '${APPNAME_UNDERSCORE}'" echo " Moved src/app → src/${APPNAME_UNDERSCORE}" echo " Replaced import statements in src/**/*.py" echo "You can now remove this script with: rm setup_project.sh" From b77cf124ee933024f020549c06089be35c01cef0 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 14:37:59 +0100 Subject: [PATCH 25/33] Test --- .github/workflows/test_setup_script.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/test_setup_script.yml b/.github/workflows/test_setup_script.yml index 50e455f..db1637e 100644 --- a/.github/workflows/test_setup_script.yml +++ b/.github/workflows/test_setup_script.yml @@ -47,6 +47,20 @@ jobs: # Check that template-python was replaced in pyproject.toml if grep -q "template-python" pyproject.toml; then echo "Error: 'template-python' still found in pyproject.toml" + exit 1 + fi + + if ! grep -q "my-test-app" pyproject.toml; then + echo "Error: 'my-test-app' not found in pyproject.toml" + exit 1 + fi + + echo "✓ All checks passed!" + + - name: Install project with new name + run: | + pip install --upgrade pip + pip install -e . - name: Test renamed command works run: | From 9d41ebac54ef41270d14dd08d1e8dbd679e025eb Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 14:47:16 +0100 Subject: [PATCH 26/33] Fixed setup_project.sh --- setup_project.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/setup_project.sh b/setup_project.sh index b3a53e1..2533997 100755 --- a/setup_project.sh +++ b/setup_project.sh @@ -29,8 +29,9 @@ else exit 1 fi -# 3. Replace import in src/**/*.py +# 3. Replace import in src/**/*.py and entry points # from app.main import main -> from .main import main +# Also replace "app.main:main" -> ".main:main" in pyproject.toml find src -type f -name "*.py" -print0 | while IFS= read -r -d '' file; do LC_ALL=C sed -i.bak \ @@ -39,6 +40,12 @@ find src -type f -name "*.py" -print0 | while IFS= read -r -d '' file; do rm -f "${file}.bak" done +# Replace app.main:main entry point in pyproject.toml +if [[ -f "pyproject.toml" ]]; then + LC_ALL=C sed -i.bak "s/app\.main:main/${APPNAME_UNDERSCORE}.main:main/g" "pyproject.toml" + rm -f "pyproject.toml.bak" +fiand entry points + echo "Done:" echo " Replaced 'template-python' → '${APPNAME}'" From fdd3848de4bba4ad42dbc299b5d19790f8251a67 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 14:50:16 +0100 Subject: [PATCH 27/33] Remove the test file in the script --- setup_project.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/setup_project.sh b/setup_project.sh index 2533997..0caeb7a 100755 --- a/setup_project.sh +++ b/setup_project.sh @@ -44,12 +44,18 @@ done if [[ -f "pyproject.toml" ]]; then LC_ALL=C sed -i.bak "s/app\.main:main/${APPNAME_UNDERSCORE}.main:main/g" "pyproject.toml" rm -f "pyproject.toml.bak" -fiand entry points +fi + +# 4. Remove the test_setup_script.yml workflow since it's no longer needed +if [[ -f ".github/workflows/test_setup_script.yml" ]]; then + rm -f ".github/workflows/test_setup_script.yml" +fi echo "Done:" echo " Replaced 'template-python' → '${APPNAME}'" echo " Replaced 'template_python' → '${APPNAME_UNDERSCORE}'" echo " Moved src/app → src/${APPNAME_UNDERSCORE}" -echo " Replaced import statements in src/**/*.py" +echo " Replaced import statements and entry points" +echo " Removed .github/workflows/test_setup_script.yml" echo "You can now remove this script with: rm setup_project.sh" From 8e1b100ecbf8ef905f3e4cd0a1c1762516ff2a12 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 14:50:46 +0100 Subject: [PATCH 28/33] Run everything relative to the script directory --- setup_project.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/setup_project.sh b/setup_project.sh index 0caeb7a..3d40f0b 100755 --- a/setup_project.sh +++ b/setup_project.sh @@ -1,6 +1,10 @@ #!/usr/bin/env bash set -euo pipefail +# Get the directory where this script is located +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + if [[ $# -ne 1 ]]; then echo "Usage: $0 " exit 1 From 359cca94caae57a0d532f37afde5e33ac8e66f11 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 15:03:44 +0100 Subject: [PATCH 29/33] Fixed docs build --- docs/source/conf.py | 5 ++++- docs/source/tutorials.rst | 2 +- setup_project.sh | 8 +++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 86d1fd8..af7ddd2 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -36,7 +36,10 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "**/.ipynb_checkpoints"] + +# nbsphinx configuration +nbsphinx_execute = "never" # Don't execute notebooks during build # -- Options for HTML output ------------------------------------------------- diff --git a/docs/source/tutorials.rst b/docs/source/tutorials.rst index 4848767..4b448a9 100644 --- a/docs/source/tutorials.rst +++ b/docs/source/tutorials.rst @@ -6,4 +6,4 @@ Here are a few tutorials to help you get started. .. toctree:: :maxdepth: 1 - tutorials/example_tutorial + tutorials/example_tutorial.ipynb diff --git a/setup_project.sh b/setup_project.sh index 3d40f0b..a245bd0 100755 --- a/setup_project.sh +++ b/setup_project.sh @@ -50,7 +50,13 @@ if [[ -f "pyproject.toml" ]]; then rm -f "pyproject.toml.bak" fi -# 4. Remove the test_setup_script.yml workflow since it's no longer needed +# 4. Update docs/source/api/index.rst to reference the new module name +if [[ -f "docs/source/api/index.rst" ]]; then + LC_ALL=C sed -i.bak "s/^ app$/ ${APPNAME_UNDERSCORE}/" "docs/source/api/index.rst" + rm -f "docs/source/api/index.rst.bak" +fi + +# 5. Remove the test_setup_script.yml workflow since it's no longer needed if [[ -f ".github/workflows/test_setup_script.yml" ]]; then rm -f ".github/workflows/test_setup_script.yml" fi From 9cd1392d596ac9d90af265f720900d66a5a5c141 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 15:06:14 +0100 Subject: [PATCH 30/33] Removed .github/workflows/test.yml --- .github/workflows/test.yml | 41 -------------------------------------- 1 file changed, 41 deletions(-) delete mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 42b12d9..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Test Pytest - -on: - push: - branches: - - main - - devel - pull_request: - branches: - - main - - devel - -jobs: - pytest: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - - name: Cache pip - uses: actions/cache@v4 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }} - restore-keys: | - ${{ runner.os }}-pip- - - - name: Install project - run: | - pip install --upgrade pip - pip install ".[test]" - - - name: Run tests - run: | - pytest . From bd11a74df802c4e968ab3072ae3ff99a56f118e1 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 15:09:24 +0100 Subject: [PATCH 31/33] copy tutorials --- docs/source/conf.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/source/conf.py b/docs/source/conf.py index af7ddd2..a687be3 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -3,10 +3,21 @@ # For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html import os +import shutil import sys +from pathlib import Path sys.path.insert(0, os.path.abspath("../src")) +# Copy tutorial notebooks from project root to docs/source/tutorials/ +tutorials_source = Path(__file__).parent.parent.parent / "tutorials" +tutorials_dest = Path(__file__).parent / "tutorials" + +if tutorials_source.exists(): + tutorials_dest.mkdir(exist_ok=True) + for notebook in tutorials_source.glob("*.ipynb"): + shutil.copy2(notebook, tutorials_dest / notebook.name) + # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information From 378605e4d2ec556809bfbd0d11ee519f1de08640 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 15:14:53 +0100 Subject: [PATCH 32/33] Fix publishing to pypi --- .github/workflows/publish_pypi.yml | 16 +++++++------ README.md | 37 ++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish_pypi.yml b/.github/workflows/publish_pypi.yml index 6a4ba69..cf03ba3 100644 --- a/.github/workflows/publish_pypi.yml +++ b/.github/workflows/publish_pypi.yml @@ -8,6 +8,12 @@ on: jobs: build-and-publish: runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/project/template-python/ + permissions: + id-token: write + contents: read steps: - name: Checkout repository @@ -21,14 +27,10 @@ jobs: - name: Install build tools run: | python -m pip install --upgrade pip - pip install build twine + pip install build - name: Build the package run: python -m build - # Uncomment to publish on pypi - #- name: Publish to PyPI - # env: - # TWINE_USERNAME: __token__ # Use API token - # TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} - # run: twine upload dist/* + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/README.md b/README.md index 8ca65e2..3cb7f82 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,40 @@ make html cd ../ open docs/_build/html/index.html ``` + +# Publishing on PyPI + +This project is configured to automatically publish to PyPI using GitHub Actions with trusted publishing (OIDC). + +## Setup (One-time configuration) + +### 1. Create PyPI Account and Project + +1. Create an account on [PyPI](https://pypi.org/) +2. Create a new project or claim your project name + +### 2. Configure Trusted Publishing on PyPI + +1. Go to your PyPI project settings +2. Navigate to "Publishing" → "Add a new publisher" +3. Configure the trusted publisher with these details: + - **PyPI Project Name**: `template-python` (or your project name) + - **Owner**: Your GitHub username/organization + - **Repository name**: `template-python` + - **Workflow name**: `publish_pypi.yml` + - **Environment name**: `pypi` + +### 3. Configure GitHub Environment (Optional but Recommended) + +1. Go to your GitHub repository → Settings → Environments +2. Create an environment named `pypi` +3. Add protection rules: + - Deployment branches: Only `main` branch + +## Publishing Process + +Once configured, publishing is automatic: + +1. **Merge to main branch**: Any push to the `main` branch triggers the workflow +2. **Automatic build**: The workflow builds the Python package +3. **Automatic publish**: The package is automatically published to PyPI using trusted publishing From 555ae61992b5e5a79c2f1f3a212ed0cd679edfd1 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 Feb 2026 15:16:21 +0100 Subject: [PATCH 33/33] Formatting with prettier --- .github/actions/build-docs/action.yml | 14 ++-- .github/workflows/publish_docs.yml | 4 +- .github/workflows/static_analysis.yml | 4 +- .github/workflows/test_docs.yml | 4 +- .github/workflows/test_pytest.yml | 2 +- .github/workflows/test_setup_script.yml | 2 +- .github/workflows/test_tutorials.yml | 2 +- .gitlab-ci.yml | 4 +- .pre-commit-config.yaml | 6 +- README.md | 1 - docs/source/_static/custom.css | 86 ++++++++++++------------- rules/devel_rules.json | 10 +-- rules/main_rules.json | 9 +-- 13 files changed, 68 insertions(+), 80 deletions(-) diff --git a/.github/actions/build-docs/action.yml b/.github/actions/build-docs/action.yml index 7795498..ca4822e 100644 --- a/.github/actions/build-docs/action.yml +++ b/.github/actions/build-docs/action.yml @@ -1,16 +1,16 @@ -name: 'Build Documentation' -description: 'Build Sphinx documentation' +name: "Build Documentation" +description: "Build Sphinx documentation" inputs: python-version: - description: 'Python version to use' + description: "Python version to use" required: false - default: '3.10' + default: "3.10" treat-warnings-as-errors: - description: 'Treat warnings as errors (-W flag)' + description: "Treat warnings as errors (-W flag)" required: false - default: 'false' + default: "false" runs: - using: 'composite' + using: "composite" steps: - name: Set up Python uses: actions/setup-python@v5 diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index 553243a..88833dd 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -28,8 +28,8 @@ jobs: - name: Build documentation uses: ./.github/actions/build-docs with: - python-version: '3.10' - treat-warnings-as-errors: 'false' + python-version: "3.10" + treat-warnings-as-errors: "false" - name: Setup Pages uses: actions/configure-pages@v5 diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index dd976df..fce5a85 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -24,7 +24,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: "3.10" - name: Run pre-commit uses: pre-commit/action@v3.0.1 @@ -52,7 +52,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: "3.10" - name: Type checking with mypy run: | diff --git a/.github/workflows/test_docs.yml b/.github/workflows/test_docs.yml index ffe898d..dce6436 100644 --- a/.github/workflows/test_docs.yml +++ b/.github/workflows/test_docs.yml @@ -24,8 +24,8 @@ jobs: - name: Build documentation uses: ./.github/actions/build-docs with: - python-version: '3.10' - treat-warnings-as-errors: 'true' + python-version: "3.10" + treat-warnings-as-errors: "true" - name: Upload docs artifact uses: actions/upload-artifact@v4 diff --git a/.github/workflows/test_pytest.yml b/.github/workflows/test_pytest.yml index 42b12d9..57c03cc 100644 --- a/.github/workflows/test_pytest.yml +++ b/.github/workflows/test_pytest.yml @@ -21,7 +21,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: "3.10" - name: Cache pip uses: actions/cache@v4 diff --git a/.github/workflows/test_setup_script.yml b/.github/workflows/test_setup_script.yml index db1637e..c1e9e4c 100644 --- a/.github/workflows/test_setup_script.yml +++ b/.github/workflows/test_setup_script.yml @@ -24,7 +24,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: "3.10" - name: Run setup script run: | diff --git a/.github/workflows/test_tutorials.yml b/.github/workflows/test_tutorials.yml index 599aa81..58a7e81 100644 --- a/.github/workflows/test_tutorials.yml +++ b/.github/workflows/test_tutorials.yml @@ -21,7 +21,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: "3.10" - name: Cache pip uses: actions/cache@v4 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d0b7c87..bbbbcf4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,14 +19,14 @@ cache: - .cache/pip before_script: - - python --version ; pip --version # For debugging + - python --version ; pip --version # For debugging - pip install virtualenv - virtualenv venv - source venv/bin/activate test: script: - - pip install ruff tox # you can also use tox + - pip install ruff tox # you can also use tox - pip install --editable ".[test]" - tox -e py,ruff diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b96501a..61316d0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,13 +6,13 @@ repos: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - - id: check-added-large-files # Prevent giant files from being committed. + - id: check-added-large-files # Prevent giant files from being committed. args: [--maxkb=500] - - id: check-merge-conflict # Check for files that contain merge conflict strings. + - id: check-merge-conflict # Check for files that contain merge conflict strings. - repo: https://github.com/kynan/nbstripout rev: 0.9.0 hooks: - - id: nbstripout # strip jupyter noteook output + - id: nbstripout # strip jupyter noteook output - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.9.1 hooks: diff --git a/README.md b/README.md index 3cb7f82..8f49086 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,6 @@ template-python # Build docs - ``` make html cd ../ diff --git a/docs/source/_static/custom.css b/docs/source/_static/custom.css index a9aa047..fb0ac08 100644 --- a/docs/source/_static/custom.css +++ b/docs/source/_static/custom.css @@ -2,92 +2,92 @@ /* Main page toctree container */ .toctree-wrapper { - margin: 2rem 0; + margin: 2rem 0; } /* Toctree list styling */ .toctree-wrapper ul { - padding-left: 0; - list-style: none; + padding-left: 0; + list-style: none; } /* Toctree list items */ .toctree-wrapper li { - margin: 0.4rem 0; - padding: 0.6rem 1rem; - border-bottom: 1.5px solid #c5d1e0; - border-left: 3px solid transparent; - transition: all 0.2s ease; + margin: 0.4rem 0; + padding: 0.6rem 1rem; + border-bottom: 1.5px solid #c5d1e0; + border-left: 3px solid transparent; + transition: all 0.2s ease; } .toctree-wrapper li:hover { - border-left-color: #4f46e5; - background: rgba(79, 70, 229, 0.03); + border-left-color: #4f46e5; + background: rgba(79, 70, 229, 0.03); } .toctree-wrapper li:last-child { - border-bottom: 1.5px solid #c5d1e0; + border-bottom: 1.5px solid #c5d1e0; } /* Toctree links */ .toctree-wrapper a.reference { - font-size: 1.1rem; - font-weight: 500; - color: #1a365d; - text-decoration: none; - display: inline-block; - transition: all 0.2s ease; - padding: 0.25rem 0; + font-size: 1.1rem; + font-weight: 500; + color: #1a365d; + text-decoration: none; + display: inline-block; + transition: all 0.2s ease; + padding: 0.25rem 0; } .toctree-wrapper a.reference:hover { - color: #2563eb; - transform: translateX(5px); + color: #2563eb; + transform: translateX(5px); } /* Nested toctree items */ .toctree-wrapper ul ul { - padding-left: 1.5rem; - margin-top: 0.3rem; + padding-left: 1.5rem; + margin-top: 0.3rem; } .toctree-wrapper ul ul li { - margin: 0.25rem 0; - padding: 0.4rem 0.8rem; - border-bottom: 1px solid #dce4f0; - border-left: 2px solid transparent; + margin: 0.25rem 0; + padding: 0.4rem 0.8rem; + border-bottom: 1px solid #dce4f0; + border-left: 2px solid transparent; } .toctree-wrapper ul ul li:hover { - border-left-color: #6366f1; - background: rgba(99, 102, 241, 0.03); + border-left-color: #6366f1; + background: rgba(99, 102, 241, 0.03); } .toctree-wrapper ul ul a.reference { - font-size: 1rem; - font-weight: 400; - color: #4a5568; + font-size: 1rem; + font-weight: 400; + color: #4a5568; } .toctree-wrapper ul ul a.reference:hover { - color: #4f46e5; + color: #4f46e5; } /* Toctree caption */ .toctree-wrapper p.caption { - font-size: 1.3rem; - font-weight: 600; - color: #1e3a5f; - margin-bottom: 1rem; - padding-bottom: 0.5rem; - border-bottom: 3px solid #4f46e5; + font-size: 1.3rem; + font-weight: 600; + color: #1e3a5f; + margin-bottom: 1rem; + padding-bottom: 0.5rem; + border-bottom: 3px solid #4f46e5; } /* Improve spacing on main page */ div.section > .toctree-wrapper { - background: linear-gradient(135deg, #f0f4f8 0%, #e8eef5 100%); - padding: 1.5rem; - border-radius: 12px; - box-shadow: 0 4px 6px rgba(79, 70, 229, 0.08); - border: 1px solid #dce4f0; + background: linear-gradient(135deg, #f0f4f8 0%, #e8eef5 100%); + padding: 1.5rem; + border-radius: 12px; + box-shadow: 0 4px 6px rgba(79, 70, 229, 0.08); + border: 1px solid #dce4f0; } diff --git a/rules/devel_rules.json b/rules/devel_rules.json index 7019204..fdcb5e2 100644 --- a/rules/devel_rules.json +++ b/rules/devel_rules.json @@ -6,10 +6,7 @@ "conditions": { "ref_name": { "exclude": [], - "include": [ - "~DEFAULT_BRANCH", - "refs/heads/devel" - ] + "include": ["~DEFAULT_BRANCH", "refs/heads/devel"] } }, "rules": [ @@ -28,10 +25,7 @@ "require_last_push_approval": true, "required_review_thread_resolution": true, "automatic_copilot_code_review_enabled": false, - "allowed_merge_methods": [ - "merge", - "squash" - ] + "allowed_merge_methods": ["merge", "squash"] } } ], diff --git a/rules/main_rules.json b/rules/main_rules.json index fe5b886..ec1cd51 100644 --- a/rules/main_rules.json +++ b/rules/main_rules.json @@ -6,10 +6,7 @@ "conditions": { "ref_name": { "exclude": [], - "include": [ - "refs/heads/master", - "refs/heads/main" - ] + "include": ["refs/heads/master", "refs/heads/main"] } }, "rules": [ @@ -28,9 +25,7 @@ "require_last_push_approval": true, "required_review_thread_resolution": true, "automatic_copilot_code_review_enabled": false, - "allowed_merge_methods": [ - "rebase" - ] + "allowed_merge_methods": ["rebase"] } } ],