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/.github/actions/build-docs/action.yml b/.github/actions/build-docs/action.yml new file mode 100644 index 0000000..ca4822e --- /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 63% rename from .github/workflows/docs.yml rename to .github/workflows/publish_docs.yml index c59b8ea..88833dd 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/publish_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: @@ -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 63% rename from .github/workflows/publish.yml rename to .github/workflows/publish_pypi.yml index d91ffc6..cf03ba3 100644 --- a/.github/workflows/publish.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,15 +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/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index 61b3cb6..fce5a85 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/.github/workflows/test_docs.yml b/.github/workflows/test_docs.yml new file mode 100644 index 0000000..dce6436 --- /dev/null +++ b/.github/workflows/test_docs.yml @@ -0,0 +1,36 @@ +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: Build documentation + uses: ./.github/actions/build-docs + with: + python-version: "3.10" + treat-warnings-as-errors: "true" + + - name: Upload docs artifact + uses: actions/upload-artifact@v4 + if: always() + with: + name: documentation + path: docs/build/html/ + retention-days: 7 diff --git a/.github/workflows/test_pytest.yml b/.github/workflows/test_pytest.yml new file mode 100644 index 0000000..57c03cc --- /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_setup_script.yml b/.github/workflows/test_setup_script.yml new file mode 100644 index 0000000..c1e9e4c --- /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 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: | + my-test-app diff --git a/.github/workflows/testing.yml b/.github/workflows/test_tutorials.yml similarity index 56% rename from .github/workflows/testing.yml rename to .github/workflows/test_tutorials.yml index f84e48c..58a7e81 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/test_tutorials.yml @@ -1,4 +1,4 @@ -name: Tests +name: Test Tutorials on: push: @@ -11,23 +11,20 @@ on: - devel jobs: - build: + tutorials: 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') }} @@ -44,23 +41,6 @@ jobs: pip install --upgrade pip pip install ".[dev]" - - name: Check installation - run: | - template-python - - - name: Run tests - run: | - pytest . - - - name: Test tutorials + - name: Execute 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 \ No newline at end of file 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/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7de373c..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 @@ -54,4 +54,3 @@ deploy: stage: deploy script: echo "Define your deployment script!" environment: production - diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index af67085..61316d0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,15 +1,21 @@ +--- repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 # Use the latest stable version + 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=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"] - + 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.9.0 hooks: - - id: nbstripout # remove jupyter notebook cell output + - id: nbstripout # strip jupyter noteook output + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.9.1 + hooks: + - id: ruff + args: [--fix, --select, I] + - id: ruff-format diff --git a/README.md b/README.md index 8ca65e2..8f49086 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,45 @@ template-python # Build docs - ``` 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 diff --git a/docs/source/_static/custom.css b/docs/source/_static/custom.css new file mode 100644 index 0000000..fb0ac08 --- /dev/null +++ b/docs/source/_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; +} 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/index.rst b/docs/source/api/index.rst new file mode 100644 index 0000000..d1bd8af --- /dev/null +++ b/docs/source/api/index.rst @@ -0,0 +1,13 @@ +API Reference +============= + +This section contains the automatically generated Python API reference. + +Modules +------- + +.. autosummary:: + :toctree: _autosummary + :recursive: + + app diff --git a/docs/source/conf.py b/docs/source/conf.py index 85ee72f..a687be3 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -2,26 +2,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")) -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) - - shutil.copytree(src, dst) - +# Copy tutorial notebooks from project root to docs/source/tutorials/ +tutorials_source = Path(__file__).parent.parent.parent / "tutorials" +tutorials_dest = Path(__file__).parent / "tutorials" -def setup(app): - app.connect("builder-inited", copy_tutorials) - # app.add_stylesheet("my-styles.css") - app.add_css_file("custom.css") +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 ----------------------------------------------------- @@ -32,46 +27,75 @@ 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", + "nbsphinx", ] -exclude_patterns = [] - -# 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 +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] -# Activate the theme. -html_theme = "sphinx_book_theme" +# 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", "**/.ipynb_checkpoints"] +# nbsphinx configuration +nbsphinx_execute = "never" # Don't execute notebooks during build -html_static_path = ["_static"] -templates_path = ["_templates"] +# -- Options for HTML output ------------------------------------------------- -# html_sidebars = {"**": []} +# 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_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..4bea978 --- /dev/null +++ b/docs/source/guides/quickstart.rst @@ -0,0 +1,16 @@ +Quickstart +========== + +First, ensure that ``template-python`` is installed on your system. + +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.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..85109c7 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,11 @@ +template-python Documentation +============================= + +Write the documentation of your python package here. + +.. toctree:: + :maxdepth: 1 + :caption: Documentation + + getting_started + 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.md deleted file mode 100644 index 84e10de..0000000 --- a/docs/source/tutorials.md +++ /dev/null @@ -1,9 +0,0 @@ -# Tutorials - -Here are a few tutorials to help you get started. - -```{toctree} -:maxdepth: 1 -:glob: - -tutorials/* \ No newline at end of file diff --git a/docs/source/tutorials.rst b/docs/source/tutorials.rst new file mode 100644 index 0000000..4b448a9 --- /dev/null +++ b/docs/source/tutorials.rst @@ -0,0 +1,9 @@ +Tutorials +========= + +Here are a few tutorials to help you get started. + +.. toctree:: + :maxdepth: 1 + + tutorials/example_tutorial.ipynb diff --git a/pyproject.toml b/pyproject.toml index ee0af26..b27f9e9 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", @@ -39,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" @@ -53,4 +52,3 @@ where = [ "src" ] [tool.isort] profile = "black" - 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/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"] } } ], diff --git a/setup_project.sh b/setup_project.sh new file mode 100755 index 0000000..a245bd0 --- /dev/null +++ b/setup_project.sh @@ -0,0 +1,71 @@ +#!/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 +fi + +APPNAME="$1" +APPNAME_UNDERSCORE="${APPNAME//-/_}" + +# 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 + +# 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 + +# 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 \ + "s/from app\.main import main/from ${APPNAME_UNDERSCORE}.main import main/g" \ + "$file" + 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" +fi + +# 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 + + +echo "Done:" +echo " Replaced 'template-python' → '${APPNAME}'" +echo " Replaced 'template_python' → '${APPNAME_UNDERSCORE}'" +echo " Moved src/app → src/${APPNAME_UNDERSCORE}" +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" 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 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!\")" ]