├── .flake8 ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug.yml │ └── feature.yml ├── dependabot.yml ├── labeler.yml ├── labels.yml └── workflows │ ├── ci.yml │ ├── label.yml │ └── templates_python.yml ├── .gitignore ├── .pre-commit-config.yaml ├── AUTHORS ├── CHANGELOG.md ├── CODEOWNERS ├── CONTRIBUTING.md ├── CONTRIBUTORS.md ├── COPYING ├── LICENSE ├── README.rst ├── doc ├── .vale.ini ├── Makefile ├── changelog.d │ ├── 538.documentation.md │ ├── 541.documentation.md │ └── changelog_template.jinja ├── make.bat ├── source │ ├── _static │ │ ├── README.md │ │ ├── basic_usage.gif │ │ └── basic_usage.tape │ ├── _templates │ │ └── README.md │ ├── changelog.rst │ ├── conf.py │ ├── getting_started │ │ └── index.rst │ ├── index.rst │ ├── templates.rst │ └── user_guide │ │ ├── index.rst │ │ ├── templating.rst │ │ └── usage.rst └── styles │ ├── .gitignore │ └── config │ └── vocabularies │ └── ANSYS │ ├── accept.txt │ └── reject.txt ├── pyproject.toml ├── src └── ansys │ └── templates │ ├── __init__.py │ ├── __main__.py │ ├── cli.py │ ├── licenses │ ├── LICENSE_MIT │ └── __init__.py │ ├── paths.py │ ├── python │ ├── common │ │ ├── cookiecutter.json │ │ └── {{cookiecutter.__project_name_slug}} │ │ │ ├── .coveragerc │ │ │ ├── .dockerignore │ │ │ ├── .flake8 │ │ │ ├── .gitattributes │ │ │ ├── .github │ │ │ ├── dependabot.yml │ │ │ ├── labeler.yml │ │ │ ├── labels.yml │ │ │ └── workflows │ │ │ │ ├── ci_cd.yml │ │ │ │ └── label.yml │ │ │ ├── .gitignore │ │ │ ├── .pre-commit-config.yaml │ │ │ ├── AUTHORS │ │ │ ├── CHANGELOG.md │ │ │ ├── CODE_OF_CONDUCT.md │ │ │ ├── CONTRIBUTING.md │ │ │ ├── CONTRIBUTORS.md │ │ │ ├── README.rst │ │ │ ├── azure-pipeline.yml │ │ │ ├── doc │ │ │ ├── .vale.ini │ │ │ ├── Makefile │ │ │ ├── changelog.d │ │ │ │ └── changelog_template.jinja │ │ │ ├── make.bat │ │ │ ├── source │ │ │ │ ├── _static │ │ │ │ │ └── README.md │ │ │ │ ├── _templates │ │ │ │ │ └── README.md │ │ │ │ ├── changelog.rst │ │ │ │ ├── conf.py │ │ │ │ ├── examples.rst │ │ │ │ ├── getting_started │ │ │ │ │ └── index.rst │ │ │ │ └── index.rst │ │ │ └── styles │ │ │ │ ├── .gitignore │ │ │ │ └── config │ │ │ │ └── vocabularies │ │ │ │ └── ANSYS │ │ │ │ ├── accept.txt │ │ │ │ └── reject.txt │ │ │ ├── docker │ │ │ └── Docker.md │ │ │ ├── examples │ │ │ └── README.md │ │ │ ├── pyproject.toml │ │ │ ├── pytest.ini │ │ │ ├── requirements_build.txt │ │ │ ├── requirements_doc.txt │ │ │ ├── requirements_tests.txt │ │ │ ├── setup.py │ │ │ ├── tests │ │ │ ├── __init__.py │ │ │ └── test_metadata.py │ │ │ └── tox.ini │ ├── doc_project │ │ ├── cookiecutter.json │ │ ├── hooks │ │ │ └── post_gen_project.py │ │ └── {{cookiecutter.__project_name_slug}} │ │ │ ├── .github │ │ │ └── workflows │ │ │ │ └── ci_cd.yml │ │ │ ├── .pre-commit-config.yaml │ │ │ ├── README.rst │ │ │ ├── ignore_words.txt │ │ │ └── tox.ini │ ├── pyace_fastapi │ │ ├── cookiecutter.json │ │ ├── hooks │ │ │ └── post_gen_project.py │ │ └── {{cookiecutter.__project_name_slug}} │ │ │ ├── docker │ │ │ ├── Dockerfile │ │ │ └── compose.yaml │ │ │ ├── examples │ │ │ └── README.md │ │ │ ├── requirements_build.txt │ │ │ ├── requirements_tests.txt │ │ │ ├── src │ │ │ ├── __init__.py │ │ │ ├── _version.py │ │ │ ├── models │ │ │ │ └── __init__.py │ │ │ ├── observability │ │ │ │ └── logger.py │ │ │ └── server.py │ │ │ └── tests │ │ │ ├── conftest.py │ │ │ ├── test_metadata.py │ │ │ └── test_server.py │ ├── pyace_flask │ │ ├── cookiecutter.json │ │ ├── hooks │ │ │ └── post_gen_project.py │ │ └── {{cookiecutter.__project_name_slug}} │ │ │ ├── docker │ │ │ ├── Dockerfile │ │ │ └── compose.yaml │ │ │ ├── examples │ │ │ └── README.md │ │ │ ├── requirements_build.txt │ │ │ ├── requirements_tests.txt │ │ │ ├── src │ │ │ ├── __init__.py │ │ │ ├── _version.py │ │ │ ├── blueprints │ │ │ │ ├── __init__.py │ │ │ │ ├── health.py │ │ │ │ └── version.py │ │ │ ├── models │ │ │ │ └── __init__.py │ │ │ ├── observability │ │ │ │ ├── __init__.py │ │ │ │ └── logger.py │ │ │ ├── server.py │ │ │ └── static │ │ │ │ └── swagger.json │ │ │ └── tests │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── test_metadata.py │ │ │ └── test_server.py │ ├── pyace_grpc │ │ ├── cookiecutter.json │ │ ├── hooks │ │ │ └── post_gen_project.py │ │ └── {{cookiecutter.__project_name_slug}} │ │ │ ├── docker │ │ │ ├── Dockerfile │ │ │ └── compose.yaml │ │ │ ├── examples │ │ │ └── README.md │ │ │ ├── protobufs │ │ │ └── pingserver.proto │ │ │ ├── requirements_build.txt │ │ │ ├── requirements_tests.txt │ │ │ ├── src │ │ │ ├── __init__.py │ │ │ ├── _version.py │ │ │ ├── client.py │ │ │ ├── observability │ │ │ │ ├── __init__.py │ │ │ │ └── logger.py │ │ │ ├── server.py │ │ │ ├── services │ │ │ │ ├── __init__.py │ │ │ │ └── pinger.py │ │ │ └── stubs │ │ │ │ └── __init__.py │ │ │ └── tests │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── test_metadata.py │ │ │ └── test_server.py │ ├── pyace_pkg │ │ ├── cookiecutter.json │ │ ├── hooks │ │ │ └── post_gen_project.py │ │ └── {{cookiecutter.__project_name_slug}} │ │ │ ├── docker │ │ │ ├── Dockerfile │ │ │ └── compose.yaml │ │ │ ├── src │ │ │ ├── __init__.py │ │ │ ├── logger.py │ │ │ └── main.py │ │ │ └── tests │ │ │ ├── __init__.py │ │ │ └── conftest.py │ ├── pyansys │ │ ├── cookiecutter.json │ │ ├── hooks │ │ │ └── post_gen_project.py │ │ └── {{cookiecutter.__project_name_slug}} │ │ │ ├── README.rst │ │ │ └── src │ │ │ └── ansys │ │ │ └── {{cookiecutter.__product_name_slug}} │ │ │ └── {{cookiecutter.__library_name_slug}} │ │ │ └── __init__.py │ ├── pyansys_advanced │ │ ├── cookiecutter.json │ │ ├── hooks │ │ │ └── post_gen_project.py │ │ └── {{cookiecutter.__project_name_slug}} │ │ │ ├── README.rst │ │ │ └── src │ │ │ └── ansys │ │ │ └── {{cookiecutter.__product_name_slug}} │ │ │ └── {{cookiecutter.__library_name_slug}} │ │ │ └── __init__.py │ ├── pyansys_openapi_client │ │ ├── cookiecutter.json │ │ ├── hooks │ │ │ └── post_gen_project.py │ │ └── {{cookiecutter.__project_name_slug}} │ │ │ ├── .github │ │ │ ├── dependabot.yml │ │ │ └── workflows │ │ │ │ ├── build_and_test_library.yml │ │ │ │ └── generate_library.yml │ │ │ ├── .m2 │ │ │ └── settings.xml │ │ │ ├── pom.xml │ │ │ └── yaml │ │ │ └── {{ cookiecutter.yaml_file_name }} │ └── pybasic │ │ ├── cookiecutter.json │ │ ├── hooks │ │ └── post_gen_project.py │ │ └── {{cookiecutter.__project_name_slug}} │ │ ├── README.rst │ │ ├── setup.py │ │ └── src │ │ └── {{cookiecutter.__project_name_slug}} │ │ └── __init__.py │ ├── testing.py │ └── utils.py ├── tests ├── test_cli.py ├── test_testing.py └── tests_templates │ └── test_python_templates.py └── tox.ini /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | exclude = .venv, __init__.py, build, doc/source/examples 3 | # To be added after refactoring code to be compliant: E501 4 | select = W191, W291, W293, W391, E115, E117, E122, E124, E125, E225, E231, E301, E303, F401, F403 5 | count = True 6 | max-complexity = 10 7 | max-line-length = 100 8 | statistics = True 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto !eol 2 | *.sh eol=lf 3 | *.bat eol=crlf -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | name: 🐞 Bug, problem, error 2 | description: Fill a bug report here 3 | title: "Bug located in ..." 4 | labels: ["bug"] 5 | assignees: [""] 6 | 7 | body: 8 | 9 | - type: checkboxes 10 | id: new-bug 11 | attributes: 12 | label: '🔍 Before submitting the issue' 13 | description: Please, make sure the following conditions are met 14 | options: 15 | - label: I have searched among the existing issues 16 | required: true 17 | - label: I am using a Python virtual environment 18 | required: true 19 | 20 | - type: textarea 21 | id: bug-description 22 | attributes: 23 | label: '🐞 Description of the bug' 24 | placeholder: Describe what bug you encountered and what should have happened. 25 | validations: 26 | required: true 27 | 28 | - type: textarea 29 | id: steps-to-reproduce 30 | attributes: 31 | label: '📝 Steps to reproduce' 32 | placeholder: Please write the steps to reproduce the issue. 33 | validations: 34 | required: true 35 | 36 | - type: dropdown 37 | id: os-name 38 | attributes: 39 | label: '💻 Which operating system are you using?' 40 | multiple: false 41 | options: 42 | - 'Windows' 43 | - 'MacOS' 44 | - 'Linux' 45 | validations: 46 | required: true 47 | 48 | - type: dropdown 49 | id: python-version 50 | attributes: 51 | label: '🐍 Which Python version are you using?' 52 | description: Run `python --version` to verify your Python version 53 | multiple: false 54 | options: 55 | - '3.8' 56 | - '3.9' 57 | - '3.10' 58 | - '3.11' 59 | validations: 60 | required: true 61 | 62 | - type: textarea 63 | id: installed-packages 64 | attributes: 65 | label: '📦 Installed packages' 66 | description: Run `python -m pip freeze` to list installed packages 67 | placeholder: Paste the output of `python -m pip freeze` here. 68 | render: shell 69 | validations: 70 | required: true 71 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | name: 💡 New feature 2 | description: Enhancements to the code 3 | title: "Add ..." 4 | labels: ["enhancement"] 5 | assignees: [""] 6 | 7 | body: 8 | 9 | - type: textarea 10 | id: feature-description 11 | attributes: 12 | label: '📝 Description of the feature' 13 | placeholder: Describe what feature you devised and why it is useful for the project 14 | validations: 15 | required: true 16 | 17 | - type: textarea 18 | id: implementation-description 19 | attributes: 20 | label: '💡 Steps for implementing the feature' 21 | validations: 22 | required: false 23 | 24 | - type: textarea 25 | id: references 26 | attributes: 27 | label: '🔗 Useful links and references' 28 | validations: 29 | required: false 30 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "pip" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "daily" 12 | labels: 13 | - "maintenance" 14 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | documentation: 2 | - changed-files: 3 | - any-glob-to-any-file: ['doc/source/**/*'] 4 | maintenance: 5 | - changed-files: 6 | - any-glob-to-any-file: ['.github/**/*', '.flake8', 'pyproject.toml'] 7 | dependencies: 8 | - changed-files: 9 | - any-glob-to-any-file: ['requirements/*'] 10 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | - name: bug 2 | description: Something isn't working 3 | color: d42a34 4 | 5 | - name: blocked 6 | description: Cannot address this till other issues are solved first 7 | color: e0b063 8 | 9 | - name: dependencies 10 | description: Related with project dependencies 11 | color: ffc0cb 12 | 13 | - name: documentation 14 | description: Improvements or additions to documentation 15 | color: 0677ba 16 | 17 | - name: enhancement 18 | description: New features or code improvements 19 | color: ffD827 20 | 21 | - name: good first issue 22 | description: Easy to solve for newcomers 23 | color: 62ca50 24 | 25 | - name: maintenance 26 | description: Package and maintenance related 27 | color: f78c37 28 | 29 | - name: release 30 | description: Anything related to an incoming release 31 | color: ffffff 32 | 33 | - name: new template 34 | description: Request for a new template 35 | color: 000000 36 | -------------------------------------------------------------------------------- /.github/workflows/label.yml: -------------------------------------------------------------------------------- 1 | name: Labeler 2 | on: 3 | pull_request: 4 | # opened, reopened, and synchronize are default for pull_request 5 | # edited - when PR title or body is changed 6 | # labeled - when labels are added to PR 7 | types: [opened, reopened, synchronize, edited, labeled] 8 | push: 9 | branches: [ main ] 10 | paths: 11 | - '../labels.yml' 12 | 13 | concurrency: 14 | group: ${{ github.workflow }}-${{ github.ref }} 15 | cancel-in-progress: true 16 | 17 | jobs: 18 | 19 | label-syncer: 20 | name: Syncer 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v4 24 | - uses: micnncim/action-label-syncer@v1 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | 28 | labeler: 29 | name: Set labels 30 | needs: [label-syncer] 31 | permissions: 32 | contents: read 33 | pull-requests: write 34 | runs-on: ubuntu-latest 35 | steps: 36 | 37 | # Label based on modified files 38 | - name: Label based on changed files 39 | uses: actions/labeler@v5 40 | with: 41 | repo-token: "${{ secrets.GITHUB_TOKEN }}" 42 | 43 | # Label based on branch name 44 | - uses: actions-ecosystem/action-add-labels@v1 45 | if: | 46 | startsWith(github.event.pull_request.head.ref, 'doc') || 47 | startsWith(github.event.pull_request.head.ref, 'docs') 48 | with: 49 | labels: documentation 50 | 51 | - uses: actions-ecosystem/action-add-labels@v1 52 | if: | 53 | startsWith(github.event.pull_request.head.ref, 'maint') || 54 | startsWith(github.event.pull_request.head.ref, 'no-ci') || 55 | startsWith(github.event.pull_request.head.ref, 'ci') 56 | with: 57 | labels: maintenance 58 | 59 | - uses: actions-ecosystem/action-add-labels@v1 60 | if: startsWith(github.event.pull_request.head.ref, 'feat') 61 | with: 62 | labels: | 63 | enhancement 64 | 65 | - uses: actions-ecosystem/action-add-labels@v1 66 | if: | 67 | startsWith(github.event.pull_request.head.ref, 'fix') || 68 | startsWith(github.event.pull_request.head.ref, 'patch') 69 | with: 70 | labels: bug 71 | 72 | commenter: 73 | runs-on: ubuntu-latest 74 | steps: 75 | - name: Suggest to add labels 76 | uses: peter-evans/create-or-update-comment@v4 77 | # Execute only when no labels have been applied to the pull request 78 | if: toJSON(github.event.pull_request.labels.*.name) == '{}' 79 | with: 80 | issue-number: ${{ github.event.pull_request.number }} 81 | body: | 82 | Please add one of the following labels to add this contribution to the Release Notes :point_down: 83 | - [bug](https://github.com/ansys/ansys-templates/pulls?q=label%3Abug+) 84 | - [documentation](https://github.com/ansys/ansys-templates/pulls?q=label%3Adocumentation+) 85 | - [enhancement](https://github.com/ansys/ansys-templates/pulls?q=label%3Aenhancement+) 86 | - [good first issue](https://github.com/ansys/ansys-templates/pulls?q=label%3Agood+first+issue) 87 | - [maintenance](https://github.com/ansys/ansys-templates/pulls?q=label%3Amaintenance+) 88 | - [release](https://github.com/ansys/ansys-templates/pulls?q=label%3Arelease+) 89 | 90 | changelog-fragment: 91 | name: "Create changelog fragment" 92 | needs: [labeler] 93 | permissions: 94 | contents: write 95 | pull-requests: write 96 | runs-on: ubuntu-latest 97 | steps: 98 | - uses: ansys/actions/doc-changelog@v8 99 | with: 100 | token: ${{ secrets.PYANSYS_CI_BOT_TOKEN }} 101 | bot-user: ${{ secrets.PYANSYS_CI_BOT_USERNAME }} 102 | bot-email: ${{ secrets.PYANSYS_CI_BOT_EMAIL }} 103 | -------------------------------------------------------------------------------- /.github/workflows/templates_python.yml: -------------------------------------------------------------------------------- 1 | name: Templates Python 2 | on: 3 | pull_request: 4 | push: 5 | tags: 6 | - "*" 7 | branches: 8 | - main 9 | workflow_dispatch: 10 | 11 | concurrency: 12 | group: ${{ github.workflow }}-${{ github.ref }} 13 | cancel-in-progress: true 14 | 15 | jobs: 16 | 17 | tests: 18 | name: ${{ matrix.cfg.template }} / ${{ matrix.cfg.build-system }} / ${{ matrix.python-version }} 19 | runs-on: ubuntu-latest 20 | strategy: 21 | matrix: 22 | python-version: ["3.9", "3.11"] 23 | include: 24 | 25 | - python-version: "3.9" 26 | toxenv: py39 27 | toxextra: keep-output 28 | 29 | - python-version: "3.11" 30 | toxenv: py311 31 | toxextra: keep-output 32 | 33 | cfg: 34 | # All pybasic template tests 35 | - {name: "doc-project", template: "doc-project", build-system: "flit", outdir: "doc_proje0/doc-project"} 36 | - {name: "doc-project", template: "doc-project", build-system: "poetry", outdir: "doc_proje1/doc-project"} 37 | - {name: "doc-project", template: "doc-project", build-system: "setuptools", outdir: "doc_proje2/doc-project"} 38 | 39 | # All pybasic template tests 40 | - {name: "pybasic", template: "pybasic", build-system: "setuptools", outdir: "pybasic_s0/pybasic"} 41 | 42 | # All pybasic template tests 43 | - {name: "pyansys", template: "pyansys", build-system: "setuptools", outdir: "pyansys_s0/pyproduct-library"} 44 | 45 | # # All pyansys_advanced template tests 46 | - {name: "pyansys-advanced-flit", template: "pyansys-advanced", build-system: "flit", outdir: "pyansys_a0/pyproduct-library"} 47 | - {name: "pyansys-advanced-poetry", template: "pyansys-advanced", build-system: "poetry", outdir: "pyansys_a1/pyproduct-library"} 48 | - {name: "pyansys-advanced-setuptools", template: "pyansys-advanced", build-system: "setuptools", outdir: "pyansys_a2/pyproduct-library"} 49 | 50 | # # All pyace template tests 51 | - {name: "pyace-pkg", template: "pyace", build-system: "setuptools", outdir: "pyace_set0/project"} 52 | - {name: "pyace-flask", template: "pyace-flask", build-system: "setuptools", outdir: "pyace_fla2/project"} 53 | - {name: "pyace-fast", template: "pyace-fast", build-system: "setuptools", outdir: "pyace_fas2/project"} 54 | - {name: "pyace-grpc", template: "pyace-grpc", build-system: "setuptools", outdir: "pyace_grp2/project"} 55 | 56 | fail-fast: false 57 | 58 | steps: 59 | - uses: actions/checkout@v4 60 | - name: Set up Python ${{ matrix.python-version }} 61 | uses: actions/setup-python@v5 62 | with: 63 | python-version: ${{ matrix.python-version }} 64 | 65 | - name: Install dependencies 66 | run: | 67 | python -m pip install --upgrade pip tox 68 | 69 | - name: Bake ${{ matrix.cfg.template }} 70 | run: | 71 | export TEMPLATE=${{ matrix.cfg.template }} 72 | tox -e ${{ matrix.toxenv }}-${{ matrix.toxextra }}-template 73 | 74 | - name: Move baked project to repo again 75 | if: matrix.python-version == '3.9' && github.event_name == 'push' 76 | run: | 77 | mv "output/test_template_python_${{ matrix.cfg.outdir }}" baked_template 78 | # GitHub Apps are not allowed to deal with .github workflows 79 | if [ -d "baked_template/.github" ]; then mv baked_template/.github baked_template/.github_demo; fi 80 | ls -a baked_template 81 | 82 | - name: Create demo branch 83 | if: matrix.python-version == '3.9' && github.event_name == 'push' 84 | uses: peterjgrainger/action-create-branch@v3.0.0 85 | env: 86 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 87 | with: 88 | branch: "demo/${{ matrix.cfg.name }}" 89 | 90 | - name: Publish demo branch 91 | if: matrix.python-version == '3.9' && github.event_name == 'push' 92 | uses: s0/git-publish-subdir-action@develop 93 | env: 94 | REPO: self 95 | BRANCH: "demo/${{ matrix.cfg.name }}" 96 | FOLDER: "baked_template" 97 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 98 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/python 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=python 3 | 4 | ### Python ### 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | *$py.class 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | wheels/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .nox/ 47 | .cov 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | *.py,cover 55 | .hypothesis/ 56 | .pytest_cache/ 57 | cover/ 58 | 59 | # Translations 60 | *.mo 61 | *.pot 62 | 63 | # Django stuff: 64 | *.log 65 | local_settings.py 66 | db.sqlite3 67 | db.sqlite3-journal 68 | 69 | # Flask stuff: 70 | instance/ 71 | .webassets-cache 72 | 73 | # Scrapy stuff: 74 | .scrapy 75 | 76 | # Sphinx documentation 77 | doc/_build/ 78 | 79 | # PyBuilder 80 | .pybuilder/ 81 | target/ 82 | 83 | # Jupyter Notebook 84 | .ipynb_checkpoints 85 | 86 | # IPython 87 | profile_default/ 88 | ipython_config.py 89 | 90 | # pyenv 91 | # For a library or package, you might want to ignore these files since the code is 92 | # intended to run in multiple environments; otherwise, check them in: 93 | # .python-version 94 | 95 | # pipenv 96 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 97 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 98 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 99 | # install all needed dependencies. 100 | #Pipfile.lock 101 | 102 | # poetry 103 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 104 | # This is especially recommended for binary packages to ensure reproducibility, and is more 105 | # commonly ignored for libraries. 106 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 107 | #poetry.lock 108 | 109 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 110 | __pypackages__/ 111 | 112 | # Celery stuff 113 | celerybeat-schedule 114 | celerybeat.pid 115 | 116 | # SageMath parsed files 117 | *.sage.py 118 | 119 | # Environments 120 | .env/ 121 | .venv 122 | env/ 123 | venv/ 124 | ENV/ 125 | env.bak/ 126 | venv.bak/ 127 | 128 | # Spyder project settings 129 | .spyderproject 130 | .spyproject 131 | 132 | # Rope project settings 133 | .ropeproject 134 | 135 | # mkdocs documentation 136 | /site 137 | 138 | # mypy 139 | .mypy_cache/ 140 | .dmypy.json 141 | dmypy.json 142 | 143 | # Pyre type checker 144 | .pyre/ 145 | 146 | # pytype static type analyzer 147 | .pytype/ 148 | 149 | # Cython debug symbols 150 | cython_debug/ 151 | 152 | # PyCharm 153 | # JetBrains specific template is maintainted in a separate JetBrains.gitignore that can 154 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 155 | # and can be added to the global gitignore or merged into this file. For a more nuclear 156 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 157 | .idea/ 158 | 159 | # Visual Studio 160 | .vs/ 161 | .vscode/* 162 | !.vscode/extensions.json 163 | 164 | # End of https://www.toptal.com/developers/gitignore/api/python 165 | 166 | # Ignore baked output cookies from debugging 167 | output/ 168 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | 3 | - repo: https://github.com/psf/black 4 | rev: 24.8.0 5 | hooks: 6 | - id: black 7 | exclude: ^src/ansys/templates/python/ 8 | 9 | - repo: https://github.com/pycqa/isort 10 | rev: 5.13.2 11 | hooks: 12 | - id: isort 13 | 14 | - repo: https://github.com/PyCQA/flake8 15 | rev: 7.1.1 16 | hooks: 17 | - id: flake8 18 | args: [ 19 | tests, 20 | ] 21 | 22 | - repo: https://github.com/codespell-project/codespell 23 | rev: v2.2.4 24 | hooks: 25 | - id: codespell 26 | exclude: 'src/ansys/templates/python/solution/{{cookiecutter.__project_name_slug}}/lock_files/dash/poetry.lock' 27 | 28 | - repo: https://github.com/pycqa/pydocstyle 29 | rev: 6.3.0 30 | hooks: 31 | - id: pydocstyle 32 | additional_dependencies: [toml] 33 | exclude: ^src/ansys/templates/python/|^tests 34 | 35 | - repo: https://github.com/pre-commit/pre-commit-hooks 36 | rev: v4.6.0 37 | hooks: 38 | - id: check-merge-conflict 39 | - id: check-yaml 40 | exclude: ^src/ansys/templates/ 41 | - id: requirements-txt-fixer 42 | - id: trailing-whitespace 43 | 44 | # Validates github workflow files 45 | - repo: https://github.com/python-jsonschema/check-jsonschema 46 | rev: 0.29.1 47 | hooks: 48 | - id: check-github-workflows 49 | 50 | - repo: https://github.com/ansys/pre-commit-hooks 51 | rev: v0.4.4 52 | hooks: 53 | - id: add-license-headers 54 | args: 55 | - --start_year=2022 56 | exclude: 'src/ansys/templates/python/' 57 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the list of ansys-templates's significant contributors. 2 | # 3 | # This file does not necessarily list everyone who has contributed code. 4 | # 5 | # For contributions made under a Corporate CLA, the organization is 6 | # added to this file. 7 | # 8 | # If you have contributed to the repository and want to be added to this file, 9 | # submit a request. 10 | # 11 | # 12 | ANSYS, Inc. -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | This project uses [towncrier](https://towncrier.readthedocs.io/) and the 4 | changes for the upcoming release can be found in 5 | this [repository file](doc/changelog.d/changelog.rst). -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | /src/ansys/templates/python/solution/ @ansys/Solution-Maintainers 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We absolutely welcome any code contributions and we hope that this 4 | guide will facilitate an understanding of the ansys-templates code 5 | repository. It is important to note that while the ansys-templates software 6 | package is maintained by ANSYS and any submissions will be reviewed 7 | thoroughly before merging, we still seek to foster a community that can 8 | support user questions and develop new features to make this software 9 | a useful tool for all users. As such, we welcome and encourage any 10 | questions or submissions to this repository. 11 | 12 | For further information about contributing to PyAnsys projects, 13 | refer to the [PyAnsys Developer's Guide](https://dev.docs.pyansys.com/). 14 | 15 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # Contributors 2 | 3 | ## Project Lead 4 | 5 | * [Jorge Martinez](https://github.com/jorgepiloto) 6 | 7 | ## Individual Contributors 8 | 9 | * [Alexander Kaszynski](https://github.com/akaszynski) 10 | * [Dan Williams](https://github.com/dnwillia-work) 11 | * [Dominik Gresch](https://github.com/greschd) 12 | * [Doug Addy](https://github.com/da1910) 13 | * [German Martinez Ayuso](https://github.com/germa89) 14 | * [Ismael Azehaf](https://github.com/iazehaf) 15 | * [Maxime Rey](https://github.com/MaxJPRey) 16 | * [Pierre Lulé](https://github.com/plule-ansys) 17 | * [Revathy Venugopal](https://github.com/Revathyvenugopal162) 18 | * [Roberto Pastor](https://github.com/RobPasMue) 19 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 ANSYS, Inc. and/or its affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 - 2025 ANSYS, Inc. and/or its affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 | of the Software, and to permit persons to whom the Software is furnished to do 10 | so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /doc/.vale.ini: -------------------------------------------------------------------------------- 1 | # Core settings 2 | # ============= 3 | 4 | # Location of our `styles` 5 | StylesPath = "styles" 6 | 7 | # The options are `suggestion`, `warning`, or `error` (defaults to “warning”). 8 | MinAlertLevel = warning 9 | 10 | # By default, `code` and `tt` are ignored. 11 | IgnoredScopes = code, tt 12 | 13 | # By default, `script`, `style`, `pre`, and `figure` are ignored. 14 | SkippedScopes = script, style, pre, figure 15 | 16 | # WordTemplate specifies what Vale will consider to be an individual word. 17 | WordTemplate = \b(?:%s)\b 18 | 19 | # List of Packages to be used for our guidelines 20 | Packages = Google 21 | 22 | # Define the Ansys vocabulary 23 | Vocab = ANSYS 24 | Vale.Terms = NO 25 | 26 | [*.{md,rst}] 27 | 28 | # Apply the following styles 29 | BasedOnStyles = Vale, Google 30 | Vale.Terms = NO -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = -j auto 6 | SPHINXBUILD = sphinx-build 7 | SOURCEDIR = source 8 | BUILDDIR = _build 9 | 10 | # Put it first so that "make" without argument is like "make help". 11 | help: 12 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 13 | 14 | .PHONY: help Makefile 15 | 16 | # Catch-all target: route all unknown targets to Sphinx using the new 17 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 18 | %: Makefile 19 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 20 | 21 | 22 | # Customized clean due to examples gallery 23 | clean: 24 | rm -rf $(BUILDDIR) 25 | rm -rf $(SOURCEDIR)/examples 26 | find . -type d -name "_autosummary" -exec rm -rf {} + 27 | 28 | # Customized pdf fov svg format images 29 | pdf: 30 | @$(SPHINXBUILD) -M latex "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 31 | cd $(BUILDDIR)/latex && latexmk -r latexmkrc -pdf *.tex -interaction=nonstopmode || true 32 | (test -f $(BUILDDIR)/latex/*.pdf && echo pdf exists) || exit 1 33 | -------------------------------------------------------------------------------- /doc/changelog.d/538.documentation.md: -------------------------------------------------------------------------------- 1 | chore: update CHANGELOG for v5.1.0 -------------------------------------------------------------------------------- /doc/changelog.d/541.documentation.md: -------------------------------------------------------------------------------- 1 | refactor: Remove solution template folder -------------------------------------------------------------------------------- /doc/changelog.d/changelog_template.jinja: -------------------------------------------------------------------------------- 1 | {% if sections[""] %} 2 | 3 | .. tab-set:: 4 | 5 | {%+ for category, val in definitions.items() if category in sections[""] %} 6 | 7 | .. tab-item:: {{ definitions[category]['name'] }} 8 | 9 | .. list-table:: 10 | :header-rows: 0 11 | :widths: auto 12 | 13 | {% for text, values in sections[""][category].items() %} 14 | * - {{ text }} 15 | - {{ values|join(', ') }} 16 | 17 | {% endfor %} 18 | {% endfor %} 19 | 20 | {% else %} 21 | No significant changes. 22 | {% endif %} 23 | -------------------------------------------------------------------------------- /doc/make.bat: -------------------------------------------------------------------------------- 1 | @echo OFF 2 | setlocal 3 | 4 | pushd %~dp0 5 | 6 | REM Command file for Sphinx documentation 7 | 8 | if "%SPHINXBUILD%" == "" ( 9 | set SPHINXBUILD=sphinx-build 10 | ) 11 | set SOURCEDIR=source 12 | set BUILDDIR=_build 13 | 14 | if "%1" == "" goto help 15 | if "%1" == "clean" goto clean 16 | if "%1" == "pdf" goto pdf 17 | 18 | %SPHINXBUILD% >NUL 2>NUL 19 | if errorlevel 9009 ( 20 | echo. 21 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 22 | echo.installed, then set the SPHINXBUILD environment variable to point 23 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 24 | echo.may add the Sphinx directory to PATH. 25 | echo. 26 | echo.If you don't have Sphinx installed, grab it from 27 | echo.http://sphinx-doc.org/ 28 | exit /b 1 29 | ) 30 | 31 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 32 | goto end 33 | 34 | :clean 35 | rmdir /s /q %BUILDDIR% > /NUL 2>&1 36 | for /d /r %SOURCEDIR% %%d in (_autosummary) do @if exist "%%d" rmdir /s /q "%%d" 37 | goto end 38 | 39 | :help 40 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 41 | 42 | :pdf 43 | %SPHINXBUILD% -M latex %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 44 | cd "%BUILDDIR%\latex" 45 | for %%f in (*.tex) do ( 46 | pdflatex "%%f" --interaction=nonstopmode) 47 | 48 | :end 49 | popd 50 | -------------------------------------------------------------------------------- /doc/source/_static/README.md: -------------------------------------------------------------------------------- 1 | Static files are to be found here (like images and other assets). 2 | -------------------------------------------------------------------------------- /doc/source/_static/basic_usage.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/ansys-templates/02e0a89e89f8faae012183afc1ccadb897a95673/doc/source/_static/basic_usage.gif -------------------------------------------------------------------------------- /doc/source/_static/basic_usage.tape: -------------------------------------------------------------------------------- 1 | # Rendering configuration 2 | Output basic_usage.gif 3 | Set FontSize 20 4 | Set Width 1920 5 | Set Height 1080 6 | 7 | # Generate a new project 8 | Type "ansys-templates new pyansys-advanced" 9 | Sleep 1000ms 10 | Enter 11 | Sleep 1000ms 12 | Enter 13 | Sleep 1000ms 14 | Enter 15 | Sleep 1000ms 16 | Enter 17 | Sleep 1000ms 18 | Enter 19 | Sleep 1000ms 20 | Enter 21 | Sleep 1000ms 22 | Enter 23 | Sleep 1000ms 24 | Enter 25 | Sleep 1000ms 26 | Enter 27 | Sleep 1000ms 28 | Enter 29 | Type "clear" 30 | Enter 31 | Sleep 1000ms 32 | 33 | # Show the structure of the generate project 34 | Type "tree pyproduct-library" 35 | Enter 36 | Sleep 5s 37 | -------------------------------------------------------------------------------- /doc/source/_templates/README.md: -------------------------------------------------------------------------------- 1 | ## Contains templates for the documentation build 2 | -------------------------------------------------------------------------------- /doc/source/getting_started/index.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (C) 2023 ANSYS, Inc. and/or its affiliates. 2 | .. SPDX-License-Identifier: MIT 3 | .. 4 | .. 5 | .. Permission is hereby granted, free of charge, to any person obtaining a copy 6 | .. of this software and associated documentation files (the "Software"), to deal 7 | .. in the Software without restriction, including without limitation the rights 8 | .. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | .. copies of the Software, and to permit persons to whom the Software is 10 | .. furnished to do so, subject to the following conditions: 11 | .. 12 | .. The above copyright notice and this permission notice shall be included in all 13 | .. copies or substantial portions of the Software. 14 | .. 15 | .. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | .. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | .. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | .. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | .. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | .. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | .. SOFTWARE. 22 | 23 | .. _ref_getting_started: 24 | 25 | Getting started 26 | =============== 27 | 28 | To successfully install ``ansys-templates``, carefully read all instructions on this page. 29 | 30 | 31 | Before installing 32 | ----------------- 33 | 34 | Several requirements must be met before you install 35 | ``ansys-templates``. 36 | 37 | 38 | Upgrading ``pip`` 39 | ^^^^^^^^^^^^^^^^^ 40 | 41 | Upgrade `pip`_ with: 42 | 43 | .. code:: bash 44 | 45 | python -m pip install --upgrade pip 46 | 47 | 48 | Installing ``pipx`` 49 | ^^^^^^^^^^^^^^^^^^^ 50 | 51 | The ``ansys-templates`` tool is built on top of Python. To ensure a clean 52 | installation, you can use `pipx`_. It ensures an isolated installation of 53 | any Python tool that you want to use. 54 | 55 | Install `pipx`_ with: 56 | 57 | .. code:: bash 58 | 59 | python -m pip install --user pipx 60 | 61 | Ensure that `pipx`_ is in your ``PATH`` with: 62 | 63 | .. code:: bash 64 | 65 | python -m pipx ensurepath 66 | 67 | If you encounter any issues when installing `pipx`_, see `pipx installation 68 | guidelines`_. 69 | 70 | 71 | Installing ansys-templates 72 | -------------------------- 73 | 74 | Once `pipx`_ is installed, proceed with the installation of 75 | ``ansys-templates`` with: 76 | 77 | .. code:: bash 78 | 79 | python -m pipx install ansys-templates 80 | 81 | 82 | Upgrading ansys-templates 83 | ------------------------- 84 | 85 | If you already have ``ansys-templates`` installed with `pipx`_, you can upgrade 86 | to the latest version with: 87 | 88 | .. code:: bash 89 | 90 | python -m pipx upgrade ansys-templates 91 | 92 | 93 | Verify your installation 94 | ------------------------ 95 | 96 | Once installed, you can verify your installation with: 97 | 98 | .. code:: bash 99 | 100 | ansys-templates --help 101 | 102 | The following code is returned: 103 | 104 | .. code:: text 105 | 106 | Usage: ansys-templates [OPTIONS] COMMAND [ARGS]... 107 | 108 | Ansys tool for creating new Ansys projects. 109 | 110 | Options: 111 | --help Show this message and exit. 112 | 113 | Commands: 114 | list List all available templates names. 115 | new Create a new project from desired template. 116 | version Display current version. 117 | 118 | .. LINKS & REFERENCES 119 | .. _pip: https://pypi.org/project/pip/ 120 | .. _pipx: https://github.com/pypa/pipx 121 | .. _pipx installation guidelines: https://pipx.pypa.io/stable/installation/ 122 | -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (C) 2023 ANSYS, Inc. and/or its affiliates. 2 | .. SPDX-License-Identifier: MIT 3 | .. 4 | .. 5 | .. Permission is hereby granted, free of charge, to any person obtaining a copy 6 | .. of this software and associated documentation files (the "Software"), to deal 7 | .. in the Software without restriction, including without limitation the rights 8 | .. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | .. copies of the Software, and to permit persons to whom the Software is 10 | .. furnished to do so, subject to the following conditions: 11 | .. 12 | .. The above copyright notice and this permission notice shall be included in all 13 | .. copies or substantial portions of the Software. 14 | .. 15 | .. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | .. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | .. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | .. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | .. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | .. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | .. SOFTWARE. 22 | 23 | .. 24 | Just reuse the root readme to avoid duplicating the documentation. 25 | Provide any documentation specific to your online documentation 26 | here. 27 | 28 | .. include:: ../../README.rst 29 | 30 | .. toctree:: 31 | :hidden: 32 | :maxdepth: 3 33 | 34 | getting_started/index 35 | user_guide/index 36 | templates 37 | changelog 38 | -------------------------------------------------------------------------------- /doc/source/user_guide/index.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (C) 2023 ANSYS, Inc. and/or its affiliates. 2 | .. SPDX-License-Identifier: MIT 3 | .. 4 | .. 5 | .. Permission is hereby granted, free of charge, to any person obtaining a copy 6 | .. of this software and associated documentation files (the "Software"), to deal 7 | .. in the Software without restriction, including without limitation the rights 8 | .. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | .. copies of the Software, and to permit persons to whom the Software is 10 | .. furnished to do so, subject to the following conditions: 11 | .. 12 | .. The above copyright notice and this permission notice shall be included in all 13 | .. copies or substantial portions of the Software. 14 | .. 15 | .. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | .. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | .. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | .. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | .. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | .. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | .. SOFTWARE. 22 | 23 | User guide 24 | ========== 25 | 26 | This section explains how to use ``ansys-templates`` and 27 | contribute by adding new templates. 28 | 29 | .. toctree:: 30 | 31 | usage 32 | templating 33 | -------------------------------------------------------------------------------- /doc/source/user_guide/usage.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (C) 2023 ANSYS, Inc. and/or its affiliates. 2 | .. SPDX-License-Identifier: MIT 3 | .. 4 | .. 5 | .. Permission is hereby granted, free of charge, to any person obtaining a copy 6 | .. of this software and associated documentation files (the "Software"), to deal 7 | .. in the Software without restriction, including without limitation the rights 8 | .. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | .. copies of the Software, and to permit persons to whom the Software is 10 | .. furnished to do so, subject to the following conditions: 11 | .. 12 | .. The above copyright notice and this permission notice shall be included in all 13 | .. copies or substantial portions of the Software. 14 | .. 15 | .. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | .. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | .. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | .. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | .. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | .. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | .. SOFTWARE. 22 | 23 | .. _ref_user_guide: 24 | 25 | 26 | How to use ``ansys-templates`` 27 | ============================== 28 | 29 | Because ``ansys-templates`` is a command line tool, its usage is intended via 30 | the command line. You can check available commands with: 31 | 32 | .. code:: bash 33 | 34 | ansys-templates --help 35 | 36 | The following help content is returned: 37 | 38 | .. code:: text 39 | 40 | Usage: ansys-templates [OPTIONS] COMMAND [ARGS]... 41 | 42 | Ansys tool for creating Python projects. 43 | 44 | Options: 45 | --help Show this message and exit. 46 | 47 | Commands: 48 | list List all available templates names. 49 | new Create a new project from desired template. 50 | version Display current version. 51 | 52 | 53 | Listing all templates 54 | --------------------- 55 | 56 | You can list all templates with: 57 | 58 | .. code:: bash 59 | 60 | ansys-templates list 61 | 62 | The following templates are returned: 63 | 64 | .. code:: text 65 | 66 | Available templates in ``ansys-templates`` are: 67 | 68 | doc-project: Create a documentation project using Sphinx. 69 | pybasic: Create a basic Python Package. 70 | pyansys: Create a PyAnsys Python Package project. 71 | pyansys-advanced: Create an advanced PyAnsys Python Package project. 72 | pyansys-openapi-client: Create an OpenAPI Client Package project. 73 | pyace: Create a Python project for any method developers. 74 | pyace-flask: Create a Flask project initialized for any developer. 75 | pyace-grpc: Create gRPC project initialized for any developer. 76 | pyace-fast: Create a FastAPI project initialized for any developer. 77 | 78 | Creating a new PyAnsys project 79 | ------------------------------ 80 | 81 | You can use a given template to create a new PyAnsys project with ``ansys-templates 82 | new`` followed by the name of the template that you want to use: 83 | 84 | .. code:: bash 85 | 86 | ansys-templates new 87 | 88 | For example, to create a new Python Package project with the pybasic template: 89 | 90 | .. code:: bash 91 | 92 | ansys-templates new pybasic 93 | 94 | You can see all templates available with ``ansys-templates list``. Or, see more 95 | information about how to use this command with: 96 | 97 | .. code:: bash 98 | 99 | ansys-templates new --help 100 | 101 | Checking the current version 102 | ---------------------------- 103 | 104 | Check the your current installed version of PyAnsys templates with: 105 | 106 | .. code:: bash 107 | 108 | ansys-templates version 109 | -------------------------------------------------------------------------------- /doc/styles/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !config 3 | !config/** 4 | !.gitignore -------------------------------------------------------------------------------- /doc/styles/config/vocabularies/ANSYS/accept.txt: -------------------------------------------------------------------------------- 1 | ANSYS 2 | Ansys 3 | ansys 4 | PyAnsys 5 | pyansys 6 | CLI 7 | pipx 8 | pytest 9 | pybasic 10 | envs 11 | namespace 12 | cookiecutter 13 | pyace 14 | pyace-fast 15 | pyace-flask 16 | pyace-grpc 17 | setuptools 18 | optiSLang 19 | 20 | -------------------------------------------------------------------------------- /doc/styles/config/vocabularies/ANSYS/reject.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/ansys-templates/02e0a89e89f8faae012183afc1ccadb897a95673/doc/styles/config/vocabularies/ANSYS/reject.txt -------------------------------------------------------------------------------- /src/ansys/templates/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. 2 | # SPDX-License-Identifier: MIT 3 | # 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | """ 24 | PyAnsys Templates. 25 | 26 | A collection of interactive templates for building Python projects from scratch 27 | according to PyAnsys guidelines. 28 | """ 29 | 30 | try: 31 | import importlib.metadata as importlib_metadata 32 | except ModuleNotFoundError: 33 | import importlib_metadata 34 | 35 | __version__ = importlib_metadata.version(__name__.replace(".", "-")) 36 | 37 | AVAILABLE_TEMPLATES_AND_DESCRIPTION = { 38 | "doc-project": "Create a documentation project using Sphinx.", 39 | "pybasic": "Create a basic Python Package.", 40 | "pyansys": "Create a PyAnsys Python Package project.", 41 | "pyansys-advanced": "Create an advanced PyAnsys Python Package project.", 42 | "pyansys-openapi_client": "Create an OpenAPI Client Package project.", 43 | "pyace": "Create a Python project for any method developers.", 44 | "pyace-flask": "Create a Flask project initialized for any developer.", 45 | "pyace-grpc": "Create gRPC project initialized for any developer.", 46 | "pyace-fast": "Create a FastAPI project initialized for any developer.", 47 | } 48 | """A list holding all available templates names.""" 49 | -------------------------------------------------------------------------------- /src/ansys/templates/__main__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. 2 | # SPDX-License-Identifier: MIT 3 | # 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | """Allows to execute ansys-templates as a Python module.""" 24 | 25 | from ansys.templates.cli import main 26 | 27 | if __name__ == "__main__": 28 | main() 29 | -------------------------------------------------------------------------------- /src/ansys/templates/cli.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. 2 | # SPDX-License-Identifier: MIT 3 | # 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | """Command Line Interface for PyAnsys Templates.""" 24 | 25 | import os 26 | 27 | import click 28 | 29 | from ansys.templates import AVAILABLE_TEMPLATES_AND_DESCRIPTION, __version__ 30 | from ansys.templates.paths import TEMPLATE_PATH_FINDER 31 | from ansys.templates.utils import bake_template 32 | 33 | 34 | def create_project(template, no_input=False, extra_context={}): 35 | """Create Python project based on a given template. 36 | 37 | Parameters 38 | ---------- 39 | template : str 40 | Name of the template to be used as basis for the project 41 | 42 | """ 43 | bake_template(TEMPLATE_PATH_FINDER[template], os.getcwd(), overwrite_if_exists=True, no_input=no_input, extra_context=extra_context) 44 | 45 | 46 | @click.group() 47 | def main(): 48 | """Ansys tool for creating new Ansys projects.""" 49 | pass 50 | 51 | 52 | @main.command() 53 | def list(): 54 | """List all available templates names.""" 55 | print("Available templates in ansys-templates are:\n") 56 | for template_name, description in AVAILABLE_TEMPLATES_AND_DESCRIPTION.items(): 57 | print(f"{template_name.replace('_', '-')}: {description}") 58 | 59 | 60 | @main.command() 61 | def version(): 62 | """Display current version.""" 63 | print(f"ansys-templates {__version__}") 64 | 65 | 66 | @main.group() 67 | def new(): 68 | """Create a new project from desired template.""" 69 | pass 70 | 71 | 72 | @new.command() 73 | def doc_project(): 74 | """Create a documentation project using Sphinx.""" 75 | create_project("doc-project") 76 | 77 | 78 | @new.command() 79 | def pybasic(): 80 | """Create a basic Python Package.""" 81 | create_project("pybasic") 82 | 83 | 84 | @new.command() 85 | def pyansys(): 86 | """Create a PyAnsys Python Package project.""" 87 | create_project("pyansys") 88 | 89 | 90 | @new.command() 91 | def pyansys_advanced(): 92 | """Create an advanced PyAnsys Python Package project.""" 93 | create_project("pyansys-advanced") 94 | 95 | 96 | @new.command() 97 | def pyansys_openapi_client(): 98 | """Create an OpenAPI Client Package project.""" 99 | create_project("pyansys-openapi-client") 100 | 101 | 102 | @new.command() 103 | def pyace(): 104 | """Create a Python project for any method developers.""" 105 | create_project("pyace") 106 | 107 | 108 | @new.command() 109 | def pyace_fast(): 110 | """Create a FastAPI project initialized for any developer.""" 111 | create_project("pyace-fast") 112 | 113 | 114 | @new.command() 115 | def pyace_flask(): 116 | """Create a Flask project initialized for any developer.""" 117 | create_project("pyace-flask") 118 | 119 | 120 | @new.command() 121 | def pyace_grpc(): 122 | """Create gRPC project initialized for any developer.""" 123 | create_project("pyace-grpc") 124 | -------------------------------------------------------------------------------- /src/ansys/templates/licenses/LICENSE_MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) {% now 'utc', '%Y' %} ANSYS, Inc. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/ansys/templates/licenses/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. 2 | # SPDX-License-Identifier: MIT 3 | # 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | """A sub-package holding various licenses templates.""" 24 | 25 | 26 | from ansys.templates.paths import LICENSES_TEMPLATES_PATH 27 | 28 | MIT_LICENSE = LICENSES_TEMPLATES_PATH / "LICENSE_MIT" 29 | """MIT license template.""" 30 | -------------------------------------------------------------------------------- /src/ansys/templates/paths.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. 2 | # SPDX-License-Identifier: MIT 3 | # 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | """A collection of useful paths pointing towards each available template.""" 24 | 25 | import os 26 | from pathlib import Path 27 | 28 | _PATHS_MODULE = Path(os.path.dirname(os.path.abspath(__file__))) 29 | 30 | LICENSES_TEMPLATES_PATH = _PATHS_MODULE / "licenses" 31 | """Path to the software licenses templates.""" 32 | 33 | PYTHON_TEMPLATES_PATH = _PATHS_MODULE / "python" 34 | """Path to the Python templates.""" 35 | 36 | PYTHON_TEMPLATES_COMMON_PATH = PYTHON_TEMPLATES_PATH / "common" 37 | """Path to the Python common template.""" 38 | 39 | PYTHON_TEMPLATES_DOC_PROJECT = PYTHON_TEMPLATES_PATH / "doc_project" 40 | """Path to the documentation project template.""" 41 | 42 | PYTHON_TEMPLATES_PYBASIC_PATH = PYTHON_TEMPLATES_PATH / "pybasic" 43 | """Path to the basic Python Package template.""" 44 | 45 | PYTHON_TEMPLATES_PYANSYS_PATH = PYTHON_TEMPLATES_PATH / "pyansys" 46 | """Path to the basic PyAnsys Python Package template.""" 47 | 48 | PYTHON_TEMPLATES_PYANSYS_ADVANCED_PATH = PYTHON_TEMPLATES_PATH / "pyansys_advanced" 49 | """Path to the advanced PyAnsys Python Package template.""" 50 | 51 | PYTHON_TEMPLATES_PYANSYS_OPENAPI_CLIENT_PATH = PYTHON_TEMPLATES_PATH / "pyansys_openapi_client" 52 | """Path to the PyAnsys OpenAPI Client Package template.""" 53 | 54 | PYTHON_TEMPLATES_PYACE_PATH = PYTHON_TEMPLATES_PATH / "pyace_pkg" 55 | """Path to the classic Python Project template.""" 56 | 57 | PYTHON_TEMPLATES_PYACE_GRPC_PATH = PYTHON_TEMPLATES_PATH / "pyace_grpc" 58 | """Path to the gRPC based Python Project template.""" 59 | 60 | PYTHON_TEMPLATES_PYACE_FLASK_PATH = PYTHON_TEMPLATES_PATH / "pyace_flask" 61 | """Path to the Flask based Python Project template.""" 62 | 63 | PYTHON_TEMPLATES_PYACE_FAST_PATH = PYTHON_TEMPLATES_PATH / "pyace_fastapi" 64 | """Path to the FastAPI based Python Project template.""" 65 | 66 | TEMPLATE_PATH_FINDER = { 67 | "common": PYTHON_TEMPLATES_COMMON_PATH, 68 | "doc-project": PYTHON_TEMPLATES_DOC_PROJECT, 69 | "pybasic": PYTHON_TEMPLATES_PYBASIC_PATH, 70 | "pyansys": PYTHON_TEMPLATES_PYANSYS_PATH, 71 | "pyansys-advanced": PYTHON_TEMPLATES_PYANSYS_ADVANCED_PATH, 72 | "pyansys-openapi-client": PYTHON_TEMPLATES_PYANSYS_OPENAPI_CLIENT_PATH, 73 | "pyace": PYTHON_TEMPLATES_PYACE_PATH, 74 | "pyace-grpc": PYTHON_TEMPLATES_PYACE_GRPC_PATH, 75 | "pyace-flask": PYTHON_TEMPLATES_PYACE_FLASK_PATH, 76 | "pyace-fast": PYTHON_TEMPLATES_PYACE_FAST_PATH, 77 | } 78 | """A dictionary relating templates names with their paths.""" 79 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "__template_name": "", 3 | "__product_name_slug": "", 4 | "__library_name_slug": "", 5 | "__project_name_slug": "", 6 | "__version": "", 7 | "__short_description": "", 8 | "__pkg_name": "", 9 | "__pkg_namespace": "", 10 | "__requires_python": "", 11 | "__repository_url": "", 12 | "__build_system": "", 13 | "__logo": "", 14 | "__logo_color": "", 15 | "__max_linelength": "", 16 | "__coverage_source": "", 17 | "__is_pyansys": "" 18 | } 19 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | source = 3 | {{ cookiecutter.__coverage_source }} 4 | 5 | [report] 6 | show_missing = true 7 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/.dockerignore: -------------------------------------------------------------------------------- 1 | **/__pycache__ 2 | **/.pytest_cache 3 | **/.classpath 4 | **/.dockerignore 5 | **/.env 6 | **/.git 7 | **/.github 8 | **/.gitignore 9 | **/.project 10 | **/.settings 11 | **/.toolstarget 12 | **/.vs 13 | **/.vscode 14 | **/*.*proj.user 15 | **/*.dbmdl 16 | **/*.jfm 17 | **/bin 18 | **/charts 19 | **/docker-compose* 20 | **/compose* 21 | **/Dockerfile* 22 | **/node_modules 23 | **/npm-debug.log 24 | **/obj 25 | **/secrets.dev.yaml 26 | **/values.dev.yaml 27 | venv 28 | README.md 29 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | exclude = venv, __init__.py, doc/_build, .venv 3 | select = W191, W291, W293, W391, E115, E117, E122, E124, E125, E225, E231, E301, E303, E501, F401, F403 4 | count = True 5 | max-complexity = 10 6 | max-line-length = {{ cookiecutter.__max_linelength }} 7 | statistics = True 8 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto !eol 2 | *.sh eol=lf 3 | *.bat eol=crlf 4 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "pip" 4 | {%- if cookiecutter.__build_system != "setuptools" %} 5 | directory: "/" 6 | {%- else -%} 7 | directory: "/requirements" 8 | {%- endif %} 9 | schedule: 10 | interval: "weekly" 11 | labels: 12 | - "maintenance" 13 | - "dependencies" 14 | 15 | - package-ecosystem: "github-actions" 16 | directory: "/" 17 | schedule: 18 | interval: "weekly" 19 | labels: 20 | - "maintenance" 21 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/.github/labeler.yml: -------------------------------------------------------------------------------- 1 | documentation: 2 | - changed-files: 3 | - any-glob-to-any-file: ['doc/source/**/*'] 4 | maintenance: 5 | - changed-files: 6 | {%- if cookiecutter.__build_system != "setuptools" %} 7 | - any-glob-to-any-file: ['.github/**/*', '.flake8', 'pyproject.toml'] 8 | {%- else -%} 9 | - any-glob-to-any-file: ['.github/**/*', '.flake8', 'requirements/*'] 10 | {%- endif %} 11 | dependencies: 12 | - changed-files: 13 | {%- if cookiecutter.__build_system != "setuptools" %} 14 | - any-glob-to-any-file: ['pyproject.toml'] 15 | {%- else -%} 16 | - any-glob-to-any-file: ['requirements/*'] 17 | {%- endif %} 18 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/.github/labels.yml: -------------------------------------------------------------------------------- 1 | - name: bug 2 | description: Something isn't working 3 | color: d42a34 4 | 5 | - name: dependencies 6 | description: Related with project dependencies 7 | color: ffc0cb 8 | 9 | - name: documentation 10 | description: Improvements or additions to documentation 11 | color: 0677ba 12 | 13 | - name: enhancement 14 | description: New features or code improvements 15 | color: FFD827 16 | 17 | - name: good first issue 18 | description: Easy to solve for newcomers 19 | color: 62ca50 20 | 21 | - name: maintenance 22 | description: Package and maintenance related 23 | color: f78c37 24 | 25 | - name: release 26 | description: Anything related to an incoming release 27 | color: ffffff 28 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/.github/workflows/label.yml: -------------------------------------------------------------------------------- 1 | name: Labeler 2 | on: 3 | pull_request: 4 | # opened, reopened, and synchronize are default for pull_request 5 | # edited - when PR title or body is changed 6 | # labeled - when labels are added to PR 7 | types: [opened, reopened, synchronize, edited, labeled] 8 | push: 9 | branches: [ main ] 10 | paths: 11 | - '../labels.yml' 12 | 13 | concurrency: 14 | group: {{ '${{ github.workflow }}-${{ github.ref }}' }} 15 | cancel-in-progress: true 16 | 17 | jobs: 18 | 19 | label-syncer: 20 | name: Syncer 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v4 24 | - uses: micnncim/action-label-syncer@v1 25 | env: 26 | GITHUB_TOKEN: {{ '${{ secrets.GITHUB_TOKEN }}' }} 27 | 28 | labeler: 29 | name: Set labels 30 | needs: [label-syncer] 31 | permissions: 32 | contents: read 33 | pull-requests: write 34 | runs-on: ubuntu-latest 35 | steps: 36 | 37 | # Label based on modified files 38 | - name: Label based on changed files 39 | uses: actions/labeler@v5 40 | with: 41 | repo-token: {{ "${{ secrets.GITHUB_TOKEN }}" }} 42 | sync-labels: true 43 | 44 | # Label based on branch name 45 | - uses: actions-ecosystem/action-add-labels@v1 46 | if: | 47 | startsWith(github.event.pull_request.head.ref, 'doc') || 48 | startsWith(github.event.pull_request.head.ref, 'docs') 49 | with: 50 | labels: documentation 51 | 52 | - uses: actions-ecosystem/action-add-labels@v1 53 | if: | 54 | startsWith(github.event.pull_request.head.ref, 'maint') || 55 | startsWith(github.event.pull_request.head.ref, 'no-ci') || 56 | startsWith(github.event.pull_request.head.ref, 'ci') 57 | with: 58 | labels: maintenance 59 | 60 | - uses: actions-ecosystem/action-add-labels@v1 61 | if: startsWith(github.event.pull_request.head.ref, 'feat') 62 | with: 63 | labels: | 64 | enhancement 65 | 66 | - uses: actions-ecosystem/action-add-labels@v1 67 | if: | 68 | startsWith(github.event.pull_request.head.ref, 'fix') || 69 | startsWith(github.event.pull_request.head.ref, 'patch') 70 | with: 71 | labels: bug 72 | 73 | commenter: 74 | runs-on: ubuntu-latest 75 | steps: 76 | - name: Suggest to add labels 77 | uses: peter-evans/create-or-update-comment@v2 78 | # Execute only when no labels have been applied to the pull request 79 | if: toJSON(github.event.pull_request.labels.*.name) == '{}' 80 | with: 81 | issue-number: {{ '${{ github.event.pull_request.number }}' }} 82 | body: | 83 | Please add one of the following labels to add this contribution to the Release Notes :point_down: 84 | - [bug]({{ cookiecutter.__repository_url }}/pulls?q=label%3Abug+) 85 | - [documentation]({{ cookiecutter.__repository_url }}/pulls?q=label%3Adocumentation+) 86 | - [enhancement]({{ cookiecutter.__repository_url }}/pulls?q=label%3Aenhancement+) 87 | - [good first issue]({{ cookiecutter.__repository_url }}/pulls?q=label%3Agood+first+issue) 88 | - [maintenance]({{ cookiecutter.__repository_url }}/pulls?q=label%3Amaintenance+) 89 | - [release]({{ cookiecutter.__repository_url }}/pulls?q=label%3Arelease+) 90 | 91 | changelog-fragment: 92 | name: "Create changelog fragment" 93 | needs: [labeler] 94 | permissions: 95 | contents: write 96 | pull-requests: write 97 | runs-on: ubuntu-latest 98 | steps: 99 | - uses: ansys/actions/doc-changelog@v6 100 | with: 101 | token: {{ '${{ secrets.PYANSYS_CI_BOT_TOKEN }}' }} -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/python 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=python 3 | 4 | ### Python ### 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | *$py.class 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | wheels/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .nox/ 47 | .cov 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | *.py,cover 55 | .hypothesis/ 56 | .pytest_cache/ 57 | cover/ 58 | 59 | # Translations 60 | *.mo 61 | *.pot 62 | 63 | # Django stuff: 64 | *.log 65 | local_settings.py 66 | db.sqlite3 67 | db.sqlite3-journal 68 | 69 | # Flask stuff: 70 | instance/ 71 | .webassets-cache 72 | 73 | # Scrapy stuff: 74 | .scrapy 75 | 76 | # Sphinx documentation 77 | doc/_build/ 78 | 79 | # PyBuilder 80 | .pybuilder/ 81 | target/ 82 | 83 | # Jupyter Notebook 84 | .ipynb_checkpoints 85 | 86 | # IPython 87 | profile_default/ 88 | ipython_config.py 89 | 90 | # pyenv 91 | # For a library or package, you might want to ignore these files since the code is 92 | # intended to run in multiple environments; otherwise, check them in: 93 | # .python-version 94 | 95 | # pipenv 96 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 97 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 98 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 99 | # install all needed dependencies. 100 | #Pipfile.lock 101 | 102 | # poetry 103 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 104 | # This is especially recommended for binary packages to ensure reproducibility, and is more 105 | # commonly ignored for libraries. 106 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 107 | #poetry.lock 108 | 109 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 110 | __pypackages__/ 111 | 112 | # Celery stuff 113 | celerybeat-schedule 114 | celerybeat.pid 115 | 116 | # SageMath parsed files 117 | *.sage.py 118 | 119 | # Environments 120 | .env 121 | .venv 122 | env/ 123 | venv/ 124 | ENV/ 125 | env.bak/ 126 | venv.bak/ 127 | 128 | # Spyder project settings 129 | .spyderproject 130 | .spyproject 131 | 132 | # Rope project settings 133 | .ropeproject 134 | 135 | # mkdocs documentation 136 | /site 137 | 138 | # mypy 139 | .mypy_cache/ 140 | .dmypy.json 141 | dmypy.json 142 | 143 | # Pyre type checker 144 | .pyre/ 145 | 146 | # pytype static type analyzer 147 | .pytype/ 148 | 149 | # Cython debug symbols 150 | cython_debug/ 151 | 152 | # PyCharm 153 | # JetBrains specific template is maintainted in a separate JetBrains.gitignore that can 154 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 155 | # and can be added to the global gitignore or merged into this file. For a more nuclear 156 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 157 | #.idea/ 158 | 159 | # End of https://www.toptal.com/developers/gitignore/api/python 160 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | 3 | - repo: https://github.com/psf/black 4 | rev: 24.8.0 5 | hooks: 6 | - id: black 7 | 8 | - repo: https://github.com/pycqa/isort 9 | rev: 5.13.2 10 | hooks: 11 | - id: isort 12 | 13 | - repo: https://github.com/PyCQA/flake8 14 | rev: 7.1.1 15 | hooks: 16 | - id: flake8 17 | 18 | - repo: https://github.com/codespell-project/codespell 19 | rev: v2.3.0 20 | hooks: 21 | - id: codespell 22 | 23 | - repo: https://github.com/pycqa/pydocstyle 24 | rev: 6.3.0 25 | hooks: 26 | - id: pydocstyle 27 | additional_dependencies: [toml] 28 | exclude: "tests/" 29 | 30 | - repo: https://github.com/pre-commit/pre-commit-hooks 31 | rev: v4.6.0 32 | hooks: 33 | - id: check-merge-conflict 34 | - id: requirements-txt-fixer 35 | - id: trailing-whitespace 36 | 37 | - repo: https://github.com/python-jsonschema/check-jsonschema 38 | rev: 0.29.1 39 | hooks: 40 | - id: check-github-workflows 41 | 42 | - repo: https://github.com/ansys/pre-commit-hooks 43 | rev: v0.4.3 44 | hooks: 45 | - id: add-license-headers 46 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the list of {{ cookiecutter.__project_name_slug }}'s significant contributors. 2 | # 3 | # This file does not necessarily list everyone who has contributed code. 4 | # 5 | # For contributions made under a Corporate CLA, the organization is 6 | # added to this file. 7 | # 8 | # If you have contributed to the repository and want to be added to this file, 9 | # submit a request. 10 | # 11 | # 12 | ANSYS, Inc. 13 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | This project uses [towncrier](https://towncrier.readthedocs.io/) and the 4 | changes for the upcoming release can be found in 5 | this [repository file](doc/source/changelog.rst). -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our 7 | project and our community a harassment-free experience for everyone, 8 | regardless of age, body size, disability, ethnicity, sex 9 | characteristics, gender identity and expression, level of experience, 10 | education, socioeconomic status, nationality, personal appearance, 11 | race, religion, or sexual identity and orientation. 12 | 13 | ## Our Standards 14 | 15 | Examples of behavior that contributes to creating a positive environment 16 | include: 17 | 18 | * Using welcoming and inclusive language 19 | * Being respectful of differing viewpoints and experiences 20 | * Gracefully accepting constructive criticism 21 | * Focusing on what is best for the community 22 | * Showing empathy towards other community members 23 | 24 | Examples of unacceptable behavior by participants include: 25 | 26 | * The use of sexualized language or imagery and unwelcome sexual 27 | attention or advances 28 | * Trolling, insulting/derogatory comments, and personal or political attacks 29 | * Public or private harassment 30 | * Publishing others' private information, such as a physical or electronic 31 | address, without explicit permission 32 | * Other conduct which could reasonably be considered inappropriate in a 33 | professional setting 34 | 35 | ## Our Responsibilities 36 | 37 | Project maintainers are responsible for clarifying the standards of acceptable 38 | behavior and are expected to take appropriate and fair corrective action in 39 | response to any instances of unacceptable behavior. 40 | 41 | Project maintainers have the right and responsibility to remove, edit, or reject 42 | comments, commits, code, wiki edits, issues, and other contributions that are 43 | not aligned to this Code of Conduct, or to ban temporarily or permanently any 44 | contributor for other behaviors that they deem inappropriate, threatening, 45 | offensive, or harmful. 46 | 47 | ## Scope 48 | 49 | This Code of Conduct applies both within project spaces and in public spaces 50 | when an individual is representing the project or its community. Examples of 51 | representing a project or community include using an official project e-mail 52 | address, posting via an official social media account, or acting as an appointed 53 | representative at an online or offline event. Representation of a project may be 54 | further defined and clarified by project maintainers. 55 | 56 | ## Attribution 57 | 58 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 59 | version 1.4, available at 60 | https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 61 | 62 | [homepage]: https://www.contributor-covenant.org 63 | 64 | For answers to common questions about this code of conduct, see 65 | https://www.contributor-covenant.org/faq 66 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # Contributors 2 | 3 | ## Project Lead or Owner 4 | 5 | * [First Last]() 6 | 7 | ## Individual Contributors 8 | 9 | * [First Last]() 10 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/README.rst: -------------------------------------------------------------------------------- 1 | {{ cookiecutter.__project_name_slug }} 2 | {{ '=' * (cookiecutter.__project_name_slug | length) }} 3 | 4 | Description 5 | ----------- 6 | 7 | {{ cookiecutter.__short_description }} 8 | 9 | 10 | How to install 11 | -------------- 12 | 13 | 14 | How to develop 15 | -------------- 16 | 17 | 18 | How to build 19 | ------------ 20 | 21 | 22 | How to deploy 23 | ------------- 24 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/azure-pipeline.yml: -------------------------------------------------------------------------------- 1 | # Python package 2 | # Create and test a Python package on multiple Python versions. 3 | # Add steps that analyze code, save the dist with the build record, publish to a PyPI-compatible index, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/python 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: ubuntu-latest 11 | strategy: 12 | Python38: 13 | python.version: '3.8' 14 | tox.env: 'py38' 15 | Python39: 16 | python.version: '3.9' 17 | tox.env: 'py39' 18 | Python310: 19 | python.version: '3.10' 20 | tox.env: 'py310' 21 | Python311: 22 | python.version: '3.11' 23 | tox.env: 'py311' 24 | 25 | steps: 26 | - task: UsePythonVersion@0 27 | inputs: 28 | versionSpec: '$(python.version)' 29 | displayName: 'Use Python $(python.version)' 30 | 31 | - script: | 32 | python -m pip install --upgrade pip 33 | pip install -r requirements.txt 34 | displayName: 'Install Dependencies' 35 | 36 | - script: | 37 | python -m pip install pre-commit tox 38 | tox -e style 39 | displayName: 'Code Style' 40 | 41 | - script: | 42 | python -m pip install pytest-azurepipelines tox 43 | tox -e $(tox.env) 44 | displayName: 'Unit Tests' 45 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/doc/.vale.ini: -------------------------------------------------------------------------------- 1 | # Core settings 2 | # ============= 3 | 4 | # Location of our `styles` 5 | StylesPath = "styles" 6 | 7 | # The options are `suggestion`, `warning`, or `error` (defaults to “warning”). 8 | MinAlertLevel = warning 9 | 10 | # By default, `code` and `tt` are ignored. 11 | IgnoredScopes = code, tt 12 | 13 | # By default, `script`, `style`, `pre`, and `figure` are ignored. 14 | SkippedScopes = script, style, pre, figure 15 | 16 | # WordTemplate specifies what Vale will consider to be an individual word. 17 | WordTemplate = \b(?:%s)\b 18 | 19 | # List of Packages to be used for our guidelines 20 | Packages = Google 21 | 22 | # Define the Ansys vocabulary 23 | Vocab = ANSYS 24 | 25 | [*.{md,rst}] 26 | 27 | # Apply the following styles 28 | BasedOnStyles = Vale, Google 29 | Vale.Terms = NO -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/doc/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = -j auto -W --color --keep-going 6 | SPHINXBUILD = sphinx-build 7 | SOURCEDIR = source 8 | BUILDDIR = _build 9 | 10 | # Put it first so that "make" without argument is like "make help". 11 | help: 12 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 13 | 14 | .PHONY: help Makefile 15 | 16 | # Catch-all target: route all unknown targets to Sphinx using the new 17 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 18 | %: Makefile 19 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 20 | 21 | 22 | # Customized clean due to examples gallery 23 | clean: 24 | rm -rf $(BUILDDIR)/* 25 | rm -rf $(SOURCEDIR)/examples 26 | find . -type d -name "_autosummary" -exec rm -rf {} + 27 | 28 | # Customized pdf for svg format images 29 | pdf: 30 | @$(SPHINXBUILD) -M latex "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 31 | cd $(BUILDDIR)/latex && latexmk -r latexmkrc -pdf *.tex -interaction=nonstopmode || true 32 | (test -f $(BUILDDIR)/latex/*.pdf && echo pdf exists) || exit 1 33 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/doc/changelog.d/changelog_template.jinja: -------------------------------------------------------------------------------- 1 | {{ '{% if sections[""] %}' }} 2 | {{ '{% for category, val in definitions.items() if category in sections[""] %}' }} 3 | 4 | {{ "{{ definitions[category]['name'] }}" }} 5 | {{ "{% set underline = '^' * definitions[category]['name']|length %}" }} 6 | {{ '{{ underline }}' }} 7 | 8 | {{ '{% for text, values in sections[""][category].items() %}' }} 9 | - {{ '{{ text }}' }} {{ "{{ values|join(', ') }}" }} 10 | {{ '{% endfor %}' }} 11 | 12 | {{ '{% endfor %}' }} 13 | {{ '{% else %}' }} 14 | No significant changes. 15 | 16 | 17 | {{ '{% endif %}' }} -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/doc/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | if "%1" == "clean" goto clean 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 30 | goto end 31 | 32 | :clean 33 | rmdir /s /q %BUILDDIR% > /NUL 2>&1 34 | for /d /r %SOURCEDIR% %%d in (_autosummary) do @if exist "%%d" rmdir /s /q "%%d" 35 | goto end 36 | 37 | :help 38 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 39 | 40 | :end 41 | popd 42 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/doc/source/_static/README.md: -------------------------------------------------------------------------------- 1 | Static files can be found here (like images and other assets). 2 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/doc/source/_templates/README.md: -------------------------------------------------------------------------------- 1 | ## Contains templates for the documentation build 2 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/doc/source/changelog.rst: -------------------------------------------------------------------------------- 1 | .. _ref_release_notes: 2 | 3 | Release notes 4 | ############# 5 | 6 | This document contains the release notes for the project. 7 | 8 | .. vale off 9 | 10 | .. towncrier release notes start 11 | 12 | .. vale on 13 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/doc/source/examples.rst: -------------------------------------------------------------------------------- 1 | Examples 2 | ######## 3 | 4 | {%- if cookiecutter.__product_name_slug != "" %} 5 | These examples demonstrate the behavior and usage of Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }}. 6 | {%- elif cookiecutter.__template_name != "solution" %} 7 | These examples demonstrate the behavior and usage of {{ cookiecutter.project_name }}. 8 | {%- else %} 9 | These examples demonstrate the behavior and usage of {{ cookiecutter.solution_name }}. 10 | {%- endif %} 11 | 12 | {{ '.. Provide links to the files in doc/source/examples below:' }} -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/doc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Just reuse the root readme to avoid duplicating the documentation. 3 | Provide any documentation specific to your online documentation 4 | here. 5 | 6 | .. include:: ../../README.rst 7 | :start-after: .. contribute_start 8 | 9 | .. toctree:: 10 | :hidden: 11 | :maxdepth: 3 12 | 13 | getting_started/index 14 | examples 15 | changelog 16 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/doc/styles/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !config 3 | !config/vocabularies 4 | !config/vocabularies/ANSYS 5 | !config/vocabularies/ANSYS/** 6 | !.gitignore -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/doc/styles/config/vocabularies/ANSYS/accept.txt: -------------------------------------------------------------------------------- 1 | ANSYS 2 | [Aa]nsys 3 | isort 4 | Makefile 5 | py 6 | pytest -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/doc/styles/config/vocabularies/ANSYS/reject.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/ansys-templates/02e0a89e89f8faae012183afc1ccadb897a95673/src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/doc/styles/config/vocabularies/ANSYS/reject.txt -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/docker/Docker.md: -------------------------------------------------------------------------------- 1 | ## Containerized deployment 2 | 3 | ### Usage 4 | 5 | #### Build 6 | 7 | ```sh 8 | $ docker build \ 9 | -f docker/Dockerfile \ 10 | -t $USER/{{cookiecutter.__project_name_slug}} \ 11 | . 12 | ``` 13 | 14 | ```ps1 15 | > docker build ` 16 | -f docker/Dockerfile ` 17 | -t $env:UserName/{{cookiecutter.__project_name_slug}} ` 18 | . 19 | ``` 20 | 21 | #### Run 22 | 23 | ```sh 24 | $ docker run \ 25 | -it \ 26 | --rm \ 27 | $USER/{{cookiecutter.__project_name_slug}} 28 | ``` 29 | 30 | ```ps1 31 | > docker run ` 32 | -it ` 33 | --rm ` 34 | $env:UserName/{{cookiecutter.__project_name_slug}} 35 | ``` 36 | 37 | #### Diagnose 38 | 39 | ```sh 40 | $ docker run \ 41 | -it \ 42 | --rm \ 43 | --entrypoint=bash \ 44 | $USER/{{cookiecutter.__project_name_slug}} 45 | ``` 46 | 47 | ```ps1 48 | > docker run ` 49 | -it ` 50 | --rm ` 51 | --entrypoint=bash ` 52 | $env:UserName/{{cookiecutter.__project_name_slug}} 53 | ``` 54 | 55 | #### Compose 56 | 57 | ```sh 58 | $ docker-compose \ 59 | -f docker/compose.yaml \ 60 | up \ 61 | --build 62 | ``` 63 | 64 | ```ps1 65 | > docker-compose ` 66 | -f docker/compose.yaml ` 67 | up ` 68 | --build 69 | ``` 70 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | python_files = test_* 3 | python_classes = Test* 4 | python_functions = test_* 5 | testpaths = tests 6 | addopts = -ra --verbose --durations=10 --color=yes 7 | 8 | markers = 9 | smoke: All critical smoke tests 10 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/requirements_build.txt: -------------------------------------------------------------------------------- 1 | build==0.10.0 2 | twine==4.0.2 3 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/requirements_doc.txt: -------------------------------------------------------------------------------- 1 | ansys-sphinx-theme==1.0.5 2 | numpydoc==1.8.0 3 | sphinx==8.0.2 4 | sphinx-copybutton==0.5.2 5 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/requirements_tests.txt: -------------------------------------------------------------------------------- 1 | pytest==7.4.3 2 | pytest-cov==4.1.0 3 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/setup.py: -------------------------------------------------------------------------------- 1 | """Project installation script.""" 2 | 3 | from setuptools import find_namespace_packages, setup 4 | 5 | setup( 6 | name="{{ cookiecutter.__pkg_name }}", 7 | version="{{ cookiecutter.__version }}", 8 | url="{{ cookiecutter.__repository_url }}", 9 | author="ANSYS, Inc.", 10 | author_email="pyansys.support@ansys.com", 11 | maintainer="PyAnsys developers", 12 | maintainer_email="pyansys.core@ansys.com", 13 | classifiers=[ 14 | "Development Status :: 4 - Beta", 15 | "Programming Language :: Python :: 3", 16 | "License :: OSI Approved :: MIT License", 17 | "Operating System :: OS Independent", 18 | ], 19 | license="MIT", 20 | license_file="LICENSE", 21 | description="{{ cookiecutter.__short_description }}", 22 | long_description=open("README.rst").read(), 23 | install_requires=["importlib-metadata >=4.0"], 24 | python_requires=">={{ cookiecutter.__requires_python }}", 25 | {%- if cookiecutter.__is_pyansys == "True" %} 26 | packages=find_namespace_packages(where="src", include="ansys*"), 27 | {%- else %} 28 | packages=find_namespace_packages(where="src"), 29 | {%- endif %} 30 | package_dir={"": "src"}, 31 | ) 32 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/ansys-templates/02e0a89e89f8faae012183afc1ccadb897a95673/src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/tests/__init__.py -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/tests/test_metadata.py: -------------------------------------------------------------------------------- 1 | from {{cookiecutter.__pkg_namespace}} import __version__ 2 | 3 | 4 | def test_pkg_version(): 5 | import importlib.metadata as importlib_metadata 6 | 7 | # Read from the pyproject.toml 8 | # major, minor, patch 9 | read_version = importlib_metadata.version("{{ cookiecutter.__pkg_name }}") 10 | 11 | assert __version__ == read_version 12 | -------------------------------------------------------------------------------- /src/ansys/templates/python/common/{{cookiecutter.__project_name_slug}}/tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | description = Default tox environments list 3 | envlist = 4 | style,{py39,py310,py311,py312}{,-coverage},doc 5 | skip_missing_interpreters = true 6 | {%- if cookiecutter.__build_system != "setuptools" %} 7 | isolated_build = true 8 | {%- if cookiecutter.__build_system == "flit" %} 9 | isolated_build_env = build 10 | {%- endif %} 11 | {%- endif %} 12 | 13 | [testenv] 14 | description = Checks for project unit tests and coverage (if desired) 15 | basepython = 16 | py39: python3.9 17 | py310: python3.10 18 | py311: python3.11 19 | py312: python3.12 20 | py: python3 21 | {%- if cookiecutter.__build_system != "poetry" %} 22 | {style,reformat,doc,build}: python3 23 | {%- else %} 24 | {style,reformat,doc}: python3 25 | {%- endif -%} 26 | {%- if cookiecutter.__build_system == "poetry" %} 27 | skip_install = true 28 | whitelist_externals = 29 | poetry 30 | {%- elif cookiecutter.__build_system == "setuptools" %} 31 | deps = 32 | -r{toxinidir}/requirements/requirements_tests.txt 33 | {%- elif cookiecutter.__build_system == "flit" %} 34 | extras = 35 | tests 36 | {%- endif %} 37 | setenv = 38 | PYTHONUNBUFFERED = yes 39 | coverage: PYTEST_EXTRA_ARGS = --cov=ansys.{{ cookiecutter.__product_name_slug }} --cov-report=term --cov-report=xml:.cov/xml --cov-report=html:.cov/html 40 | commands = 41 | {%- if cookiecutter.__build_system != "poetry" %} 42 | pytest {env:PYTEST_MARKERS:} {env:PYTEST_EXTRA_ARGS:} {posargs:-vv} 43 | {%- else -%} 44 | poetry install 45 | poetry run pytest {env:PYTEST_MARKERS:} {env:PYTEST_EXTRA_ARGS:} {posargs:-vv} 46 | {%- endif %} 47 | 48 | [testenv:style] 49 | description = Checks project code style 50 | skip_install = true 51 | deps = 52 | pre-commit 53 | commands = 54 | pre-commit install 55 | pre-commit run --all-files --show-diff-on-failure 56 | 57 | [testenv:doc] 58 | description = Check if documentation generates properly 59 | {%- if cookiecutter.__build_system == "setuptools" %} 60 | deps = 61 | -r{toxinidir}/requirements/requirements_doc.txt 62 | {%- elif cookiecutter.__build_system == "poetry" %} 63 | skip_install = true 64 | whitelist_externals = 65 | poetry 66 | {%- elif cookiecutter.__build_system == "flit" %} 67 | extras = 68 | doc 69 | {%- endif %} 70 | commands = 71 | {%- if cookiecutter.__build_system != "poetry" %} 72 | sphinx-build -d "{toxworkdir}/doc_doctree" doc/source "{toxinidir}/_build/html" --color -vW -bhtml 73 | {%- elif cookiecutter.__build_system == "poetry" %} 74 | poetry install 75 | poetry run sphinx-build -d "{toxworkdir}/doc_doctree" doc/source "{toxinidir}/_build/html" --color -vW -bhtml 76 | {%- endif %} 77 | -------------------------------------------------------------------------------- /src/ansys/templates/python/doc_project/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "__template_name": "doc-project", 3 | "project_name": "doc-project", 4 | "__project_name": "{{ cookiecutter.project_name }} | lower", 5 | "__project_name_slug": "{{ cookiecutter.project_name }}", 6 | "version": "0.1.dev0", 7 | "__version": "{{ cookiecutter.version }}", 8 | "short_description": "", 9 | "__short_description": "{{ cookiecutter.short_description | capitalize }}", 10 | "__pkg_name": "", 11 | "__pkg_namespace": "", 12 | "requires_python": ["3.9", "3.10", "3.11", "3.12"], 13 | "__requires_python": "{{ cookiecutter.requires_python }}", 14 | "repository_url": "https://github.com/ansys/{{ cookiecutter.__project_name_slug }}", 15 | "__repository_url": "{{ cookiecutter.repository_url }}", 16 | "__documentation_url": "", 17 | "build_system": ["flit", "poetry", "setuptools"], 18 | "__build_system": "{{ cookiecutter.build_system }}", 19 | "logo": ["Ansys", "PyAnsys"], 20 | "__logo": "{{ cookiecutter.logo | lower }}", 21 | "__logo_color": "black", 22 | "max_linelength": "100", 23 | "__max_linelength": "{{ cookiecutter.max_linelength }}", 24 | "__coverage_source": "", 25 | "__product_name_slug": "", 26 | "__library_name_slug": "", 27 | "__is_pyansys": "False" 28 | } 29 | -------------------------------------------------------------------------------- /src/ansys/templates/python/doc_project/hooks/post_gen_project.py: -------------------------------------------------------------------------------- 1 | """Post-processing script for cleaning the raw rendered project.""" 2 | import os 3 | import shutil 4 | from pathlib import Path 5 | 6 | import isort 7 | 8 | from ansys.templates.utils import keep_files 9 | 10 | 11 | ALLOWED_BUILD_SYSTEMS = ["flit", "poetry", "setuptools"] 12 | """A list of all allowed build systems by the template.""" 13 | 14 | DESIRED_STRUCTURE = [ 15 | "CHANGELOG.md", 16 | "CODE_OF_CONDUCT.md", 17 | "CONTRIBUTING.md", 18 | "doc/changelog.d/changelog_template.jinja", 19 | "doc/Makefile", 20 | "doc/make.bat", 21 | "doc/.vale.ini", 22 | "doc/styles/.gitignore", 23 | "doc/styles/config/vocabularies/ANSYS/accept.txt", 24 | "doc/styles/config/vocabularies/ANSYS/reject.txt", 25 | "doc/source/getting_started/index.rst", 26 | "doc/source/changelog.rst", 27 | "doc/source/conf.py", 28 | "doc/source/examples.rst", 29 | "doc/source/index.rst", 30 | "doc/source/_static/README.md", 31 | "doc/source/_templates/README.md", 32 | "examples/README.md", 33 | ".github/dependabot.yml", 34 | ".github/labeler.yml", 35 | ".github/labels.yml", 36 | ".github/workflows/ci_cd.yml", 37 | ".github/workflows/label.yml", 38 | ".gitignore", 39 | "LICENSE", 40 | "README.rst", 41 | ".pre-commit-config.yaml", 42 | "requirements/requirements_build.txt", 43 | "requirements/requirements_doc.txt", 44 | "tox.ini", 45 | ] 46 | """A list holding all desired files to be included in the project.""" 47 | 48 | 49 | def main(): 50 | """Entry point of the script.""" 51 | # Get baked project location path 52 | project_path = Path(os.getcwd()) 53 | 54 | # Move all requirements files into a requirements/ directory 55 | os.mkdir(project_path / "requirements") 56 | requirements_files = [ 57 | f"requirements_{name}.txt" for name in ["build", "doc"] 58 | ] 59 | for file in requirements_files: 60 | shutil.move(str(project_path / file), str(project_path / "requirements")) 61 | 62 | # Apply isort with desired config 63 | isort_config = isort.settings.Config( 64 | line_length="{{ cookiecutter.__max_linelength }}", 65 | profile="black", 66 | ) 67 | filepaths_list = [ 68 | project_path / "doc" / "source" / "conf.py", 69 | ] 70 | for filepath in filepaths_list: 71 | isort.api.sort_file(filepath, config=isort_config) 72 | 73 | # Apply the desired structure to the project 74 | keep_files(DESIRED_STRUCTURE) 75 | 76 | if __name__ == "__main__": 77 | main() 78 | -------------------------------------------------------------------------------- /src/ansys/templates/python/doc_project/{{cookiecutter.__project_name_slug}}/.github/workflows/ci_cd.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | push: 6 | tags: 7 | - "*" 8 | branches: 9 | - main 10 | 11 | env: 12 | MAIN_PYTHON_VERSION: '{{ cookiecutter.__requires_python }}' 13 | 14 | concurrency: 15 | group: {{ '${{ github.workflow }}-${{ github.ref }}' }} 16 | cancel-in-progress: true 17 | 18 | jobs: 19 | 20 | style: 21 | name: Code style 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v3 25 | - name: Set up Python 26 | uses: actions/setup-python@v4 27 | with: 28 | python-version: {{ '${{ env.MAIN_PYTHON_VERSION }}' }} 29 | - name: Install dependencies 30 | run: | 31 | python -m pip install --upgrade pip tox 32 | - name: Test with tox 33 | run: tox -e style 34 | 35 | docs-style: 36 | name: Documentation Style Check 37 | runs-on: ubuntu-latest 38 | steps: 39 | - uses: actions/checkout@v3 40 | 41 | - name: Running Vale 42 | uses: errata-ai/vale-action@reviewdog 43 | env: 44 | GITHUB_TOKEN: {{ '${{secrets.GITHUB_TOKEN}}' }} 45 | with: 46 | files: doc 47 | reporter: github-pr-check 48 | level: error 49 | filter_mode: nofilter 50 | fail_on_error: true 51 | vale_flags: "--config=doc/.vale.ini" 52 | 53 | docs: 54 | name: Documentation 55 | needs: [style, docs-style] 56 | runs-on: ubuntu-latest 57 | steps: 58 | - uses: actions/checkout@v3 59 | 60 | - name: Set up Python 61 | uses: actions/setup-python@v4 62 | with: 63 | python-version: {{ '${{ env.MAIN_PYTHON_VERSION }}' }} 64 | 65 | - name: Install system dependencies 66 | run: | 67 | sudo apt-get update 68 | sudo apt-get install -y texlive-latex-extra latexmk nodejs npm graphviz 69 | npm install -g @mermaid-js/mermaid-cli 70 | 71 | - name: Install Python dependencies 72 | run: | 73 | python -m pip install --upgrade pip tox 74 | 75 | - name: Build HTML documentation 76 | run: tox -e doc 77 | 78 | - name: Build PDF Documentation 79 | run: | 80 | sudo apt update 81 | sudo apt-get install -y texlive-latex-extra latexmk 82 | python -m pip install -r requirements/requirements_doc.txt 83 | make -C doc pdf 84 | 85 | - name: Upload HTML documentation 86 | uses: actions/upload-artifact@v3.1.0 87 | with: 88 | name: HTML-Documentation 89 | path: .tox/doc_out_html/ 90 | retention-days: 7 91 | 92 | - name: Upload PDF Documentation 93 | uses: actions/upload-artifact@v3.1.0 94 | with: 95 | name: PDF-Documentation 96 | path: doc/build/latex/*.pdf 97 | retention-days: 7 98 | 99 | - name: Deploy to gh-pages 100 | if: github.event_name == 'push' 101 | uses: JamesIves/github-pages-deploy-action@v4 102 | with: 103 | GITHUB_TOKEN: {{ '${{ secrets.GITHUB_TOKEN }}' }} 104 | BRANCH: gh-pages 105 | FOLDER: .tox/doc_out_html/ 106 | CLEAN: true 107 | SINGLE_COMMIT: true 108 | 109 | release: 110 | if: github.event_name == 'push' && contains(github.ref, 'refs/tags') 111 | needs: [style, docs-style, docs] 112 | runs-on: ubuntu-latest 113 | steps: 114 | - uses: actions/checkout@v3 115 | 116 | - uses: actions/download-artifact@v3 117 | 118 | - name: Display structure of downloaded files 119 | run: ls -R 120 | 121 | - name: Release 122 | uses: softprops/action-gh-release@v1 123 | with: 124 | generate_release_notes: true 125 | files: | 126 | ./*PDF*/*.pdf 127 | -------------------------------------------------------------------------------- /src/ansys/templates/python/doc_project/{{cookiecutter.__project_name_slug}}/.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | 3 | - repo: https://github.com/psf/black 4 | rev: 23.1.0 5 | hooks: 6 | - id: black 7 | args: ["doc/"] 8 | 9 | - repo: https://github.com/pycqa/isort 10 | rev: 5.12.0 11 | hooks: 12 | - id: isort 13 | args: [ 14 | "--profile", "black", 15 | "--force-sort-within-sections", 16 | "--line-length", "100", 17 | ] 18 | 19 | - repo: https://github.com/PyCQA/flake8 20 | rev: 6.0.0 21 | hooks: 22 | - id: flake8 23 | 24 | - repo: https://github.com/codespell-project/codespell 25 | rev: v2.2.2 26 | hooks: 27 | - id: codespell 28 | args: [--ignore-words=doc/styles/config/vocabularies/ANSYS/accept.txt, -S \*.pyc\,\*.xml\,\*.txt\,\*.gif\,\*.png\,\*.jpg\,\*.js\,\*.html\,\*.doctree\,\*.ttf\,\*.woff\,\*.woff2\,\*.eot\,\*.mp4\,\*.inv\,\*.pickle\,\*.ipynb\,flycheck\*\,./.git/\*\,./.hypothesis/\*\,\*.yml\,./doc/build/\*\,./doc/images/\*\,./dist/\*\,\*~\,.hypothesis\*\,./doc/source/examples/\*\,\*cover\,\*.dat\,\*.mac] 29 | 30 | - repo: https://github.com/pre-commit/pre-commit-hooks 31 | rev: v4.4.0 32 | hooks: 33 | - id: check-merge-conflict 34 | - id: debug-statements 35 | 36 | - repo: https://github.com/python-jsonschema/check-jsonschema 37 | rev: 0.21.0 38 | hooks: 39 | - id: check-github-workflows 40 | name: "Check GitHub workflows" 41 | files: ^\.github/workflows/ 42 | types: [yaml] 43 | 44 | -------------------------------------------------------------------------------- /src/ansys/templates/python/doc_project/{{cookiecutter.__project_name_slug}}/README.rst: -------------------------------------------------------------------------------- 1 | {{ cookiecutter.__project_name_slug }} 2 | {{ '=' * (cookiecutter.__project_name_slug | length) }} 3 | 4 | {{ cookiecutter.__short_description }} 5 | 6 | 7 | How to install 8 | -------------- 9 | 10 | 11 | Code Style 12 | ---------- 13 | Code style can be checked by running: 14 | 15 | .. code-block:: text 16 | 17 | tox -e style 18 | 19 | Previous command will run `pre-commit`_ for checking code quality. 20 | 21 | 22 | Documentation 23 | ------------- 24 | Documentation can be rendered by running: 25 | 26 | .. code-block:: text 27 | 28 | tox -e doc 29 | 30 | The resultant HTML files can be inspected using your favorite web browser: 31 | 32 | .. code-block:: text 33 | 34 | .tox/doc_out_html/index.html 35 | 36 | Previous will open the rendered documentation in the desired browser. 37 | 38 | 39 | .. LINKS AND REFERENCES 40 | .. _black: https://github.com/psf/black 41 | .. _flake8: https://flake8.pycqa.org/en/latest/ 42 | .. _isort: https://github.com/PyCQA/isort 43 | .. _PyAnsys Developer's guide: https://dev.docs.pyansys.com/ 44 | .. _pre-commit: https://pre-commit.com/ 45 | .. _pytest: https://docs.pytest.org/en/stable/ 46 | .. _Sphinx: https://www.sphinx-doc.org/en/master/ 47 | .. _pip: https://pypi.org/project/pip/ 48 | .. _tox: https://tox.wiki/ 49 | .. _venv: https://docs.python.org/3/library/venv.html 50 | -------------------------------------------------------------------------------- /src/ansys/templates/python/doc_project/{{cookiecutter.__project_name_slug}}/ignore_words.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/ansys-templates/02e0a89e89f8faae012183afc1ccadb897a95673/src/ansys/templates/python/doc_project/{{cookiecutter.__project_name_slug}}/ignore_words.txt -------------------------------------------------------------------------------- /src/ansys/templates/python/doc_project/{{cookiecutter.__project_name_slug}}/tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | description = Default environments to be executed when calling tox 3 | envlist = 4 | style 5 | doc 6 | isolated_build = true 7 | isolated_build_env = build 8 | skipsdist = true 9 | 10 | [testenv] 11 | description = Generic environment configuration 12 | basepython = 13 | {style,doc,build}: python3 14 | passenv = * 15 | setenv = 16 | PYTHONUNBUFFERED = yes 17 | skip_install = false 18 | 19 | [testenv:style] 20 | description = Checks if code style applies 21 | skip_install = true 22 | deps = 23 | pre-commit 24 | commands = 25 | pre-commit install 26 | pre-commit run --all-files --show-diff-on-failure 27 | 28 | [testenv:doc] 29 | description = Checks if project documentation properly builds 30 | skip_install = false 31 | deps = 32 | -r{toxinidir}/requirements/requirements_doc.txt 33 | allowlist_externals=* 34 | commands = 35 | sphinx-build -d "{toxworkdir}/doc_doctree" doc/source "{toxworkdir}/doc_out_html" --color -vW -b html 36 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "__template_name": "pyace-fastapi", 3 | "project_name": "project", 4 | "__project_name_slug": "{{ cookiecutter.project_name | slugify(separator=('_')) }}", 5 | "library_name": "library", 6 | "ci_cd_platform": ["GitHub", "Azure DevOps"], 7 | "enable_docker": ["No", "Yes"], 8 | "enable_full_observability_stack": ["No", "Yes"], 9 | "copyright": "None", 10 | "__default_copyright": "{{ cookiecutter.copyright }}", 11 | "__library_name_slug": "{{ cookiecutter.library_name | slugify(separator=('_')) }}", 12 | "__pkg_name": "{{ cookiecutter.__project_name_slug | replace('_', '-') }}-{{ cookiecutter.__library_name_slug | replace('_', '-') }}", 13 | "__pkg_namespace": "src", 14 | "version": "0.1.dev0", 15 | "__version": "{{ cookiecutter.version }}", 16 | "short_description": "A {{ cookiecutter.project_name }} Python project for {{ cookiecutter.project_name }} {{ cookiecutter.library_name }}", 17 | "__short_description": "{{ cookiecutter.short_description }}", 18 | "repository_url": "https://github.com/ansys/{{ cookiecutter.__project_name_slug }}", 19 | "__repository_url": "{{ cookiecutter.repository_url }}", 20 | "__documentation_url": "", 21 | "requires_python": ["3.9", "3.10", "3.11", "3.12"], 22 | "__requires_python": "{{ cookiecutter.requires_python }}", 23 | "build_system": "setuptools", 24 | "__build_system": "setuptools", 25 | "logo": ["Ansys", "PyAnsys"], 26 | "__logo": "{{ cookiecutter.logo | lower }}", 27 | "logo_color": ["white", "black"], 28 | "__logo_color": "{{ cookiecutter.logo_color }}", 29 | "max_linelength": "100", 30 | "__max_linelength": "{{ cookiecutter.max_linelength }}", 31 | "__coverage_source": "", 32 | "__product_name_slug": "", 33 | "__is_pyansys": "False" 34 | } 35 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/hooks/post_gen_project.py: -------------------------------------------------------------------------------- 1 | """Post-processing script for cleaning the raw rendered project.""" 2 | import os 3 | import shutil 4 | from pathlib import Path 5 | 6 | import isort 7 | 8 | from ansys.templates.utils import keep_files 9 | 10 | DESIRED_STRUCTURE = [ 11 | "AUTHORS", 12 | "CHANGELOG.md", 13 | "CODE_OF_CONDUCT.md", 14 | "CONTRIBUTING.md", 15 | "CONTRIBUTORS.md", 16 | "doc/changelog.d/changelog_template.jinja", 17 | "doc/Makefile", 18 | "doc/make.bat", 19 | "doc/.vale.ini", 20 | "doc/styles/.gitignore", 21 | "doc/styles/config/vocabularies/ANSYS/accept.txt", 22 | "doc/styles/config/vocabularies/ANSYS/reject.txt", 23 | "doc/source/changelog.rst", 24 | "doc/source/conf.py", 25 | "doc/source/examples.rst", 26 | "doc/source/getting_started/index.rst", 27 | "doc/source/index.rst", 28 | "doc/source/_static/README.md", 29 | "doc/source/_templates/README.md", 30 | "examples/README.md", 31 | ".flake8", 32 | ".gitattributes", 33 | ".gitignore", 34 | "LICENSE", 35 | ".pre-commit-config.yaml", 36 | "pyproject.toml", 37 | "README.rst", 38 | "requirements/requirements_build.txt", 39 | "requirements/requirements_doc.txt", 40 | "requirements/requirements_tests.txt", 41 | "setup.py", 42 | "src/__init__.py", 43 | "src/_version.py", 44 | "src/server.py", 45 | "src/models/__init__.py", 46 | "src/observability/logger.py", 47 | "tests/test_metadata.py", 48 | "tests/test_server.py", 49 | "tests/conftest.py", 50 | "tox.ini" 51 | ] 52 | """A list holding all desired files to be included in the project.""" 53 | 54 | 55 | def main(): 56 | """Entry point of the script.""" 57 | # Get baked project location path 58 | project_path = Path(os.getcwd()) 59 | 60 | # Move all requirements files into a requirements/ directory 61 | os.mkdir(project_path / "requirements") 62 | requirements_files = [ 63 | f"requirements_{name}.txt" for name in ["build", "doc", "tests"] 64 | ] 65 | for file in requirements_files: 66 | shutil.move(str(project_path / file), str(project_path / "requirements")) 67 | 68 | # Apply isort with desired config 69 | isort_config = isort.settings.Config( 70 | line_length="{{ cookiecutter.__max_linelength }}", 71 | profile="black", 72 | ) 73 | filepaths_list = [ 74 | project_path / "doc/source/conf.py", 75 | ] 76 | for filepath in filepaths_list: 77 | isort.api.sort_file(filepath, isort_config) 78 | 79 | # Remove ci/cd non-desired files 80 | ci_cd = "{{ cookiecutter.ci_cd_platform }}" 81 | if ci_cd == 'GitHub': 82 | DESIRED_STRUCTURE.extend( 83 | [ 84 | ".github/dependabot.yml", 85 | ".github/labeler.yml", 86 | ".github/labels.yml", 87 | ".github/workflows/ci_cd.yml", 88 | ".github/workflows/label.yml", 89 | ] 90 | ) 91 | if ci_cd == 'Azure DevOps': 92 | DESIRED_STRUCTURE.append("azure-pipeline.yml") 93 | 94 | # Remove docker non desired files 95 | enable_docker = "{{ cookiecutter.enable_docker }}" 96 | if enable_docker == 'Yes': 97 | DESIRED_STRUCTURE.append("docker/compose.yaml") 98 | DESIRED_STRUCTURE.append("docker/Dockerfile") 99 | DESIRED_STRUCTURE.append("docker/Docker.md") 100 | DESIRED_STRUCTURE.append(".dockerignore") 101 | 102 | # Remove non-desired files 103 | keep_files(DESIRED_STRUCTURE) 104 | 105 | 106 | if __name__ == "__main__": 107 | main() 108 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/{{cookiecutter.__project_name_slug}}/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # --------------------------- 2 | FROM python:{{ cookiecutter.requires_python }}-slim AS base 3 | 4 | ENV PYTHONDONTWRITEBYTECODE=1 5 | ENV PYTHONUNBUFFERED=1 6 | 7 | RUN apt-get update \ 8 | && apt-get install -y \ 9 | && rm -rf /var/lib/apt/lists/* 10 | 11 | WORKDIR /app 12 | 13 | COPY requirements/requirements_build.txt . 14 | 15 | RUN pip install --no-cache-dir --upgrade pip && \ 16 | pip install --no-cache-dir -r requirements_build.txt 17 | 18 | # --------------------------- 19 | FROM base AS test 20 | 21 | COPY requirements/requirements_tests.txt . 22 | 23 | RUN pip install --no-cache-dir -r requirements_test.txt 24 | 25 | COPY . . 26 | 27 | RUN pytest tests 28 | 29 | # --------------------------- 30 | FROM base AS final 31 | LABEL org.opencontainers.image.authors={{ cookiecutter.__project_name_slug }} 32 | 33 | EXPOSE 80 34 | 35 | COPY src . 36 | 37 | ENTRYPOINT [ "uvicorn", "server:app", "--host", "0.0.0.0", "--port", "80" ] -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/{{cookiecutter.__project_name_slug}}/docker/compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3.9' 2 | 3 | services: 4 | {{ cookiecutter.library_name }}-api: 5 | image: {{ cookiecutter.__project_name_slug }}/{{ cookiecutter.__library_name_slug }}-api 6 | build: 7 | context: .. 8 | dockerfile: ./docker/Dockerfile 9 | ports: 10 | - "50050:80" 11 | networks: 12 | - {{ cookiecutter.__project_name_slug }} 13 | 14 | {% if cookiecutter.enable_full_observability_stack == 'Yes' -%} 15 | 16 | # OPENTELEMETRY COLLECTOR 17 | 18 | otel-collector: 19 | image: otel/opentelemetry-collector-contrib:0.55.0 20 | command: [ "--config=/etc/otel-collector-config.yaml" ] 21 | volumes: 22 | - ./_deploy/otel-collector-config.yaml:/etc/otel-collector-config.yaml 23 | - /mnt/{{ cookiecutter.__project_name_slug }}/AppData/Local/Otel:/etc/output:rw # Store the logs 24 | ports: 25 | - "8888:8888" # Prometheus metrics exposed by the collector 26 | - "8889:8889" # Prometheus exporter metrics 27 | - "4317:4317" # OTLP gRPC receiver 28 | - "13133:13133" # Health check 29 | networks: 30 | - {{ cookiecutter.__project_name_slug }} 31 | {% endif %} 32 | 33 | 34 | 35 | networks: 36 | {{ cookiecutter.__project_name_slug }}: 37 | name: {{ cookiecutter.__project_name_slug }}-stream 38 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/{{cookiecutter.__project_name_slug}}/examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/{{cookiecutter.__project_name_slug}}/requirements_build.txt: -------------------------------------------------------------------------------- 1 | build>=0.7.0 2 | fastapi 3 | pydantic 4 | twine>=3.8 5 | uvicorn 6 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/{{cookiecutter.__project_name_slug}}/requirements_tests.txt: -------------------------------------------------------------------------------- 1 | coverage==6.2 2 | docker 3 | fastapi 4 | pydantic 5 | pytest>=7.1.0 6 | pytest-cov>=3.0.0 7 | pytest-flakes==4.0.5 8 | pytest-pep8 9 | uvicorn 10 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/{{cookiecutter.__project_name_slug}}/src/__init__.py: -------------------------------------------------------------------------------- 1 | """{{ cookiecutter.__project_name_slug }}.""" 2 | {%- if cookiecutter.copyright != "None" %} 3 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 4 | {% endif %} 5 | 6 | import os 7 | import sys 8 | 9 | from ._version import __version__ 10 | 11 | sys.path.append(os.path.join(os.path.dirname(__file__))) 12 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/{{cookiecutter.__project_name_slug}}/src/_version.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | __version__ = "{{ cookiecutter.__version }}" 5 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/{{cookiecutter.__project_name_slug}}/src/models/__init__.py: -------------------------------------------------------------------------------- 1 | """Models module.""" 2 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/{{cookiecutter.__project_name_slug}}/src/observability/logger.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | """ 5 | {{ cookiecutter.project_name }}. 6 | 7 | {{ cookiecutter.library_name }} 8 | """ 9 | from datetime import datetime 10 | import logging 11 | import os 12 | 13 | 14 | class Logger(object): 15 | """Logger class.""" 16 | 17 | @classmethod 18 | def init(cls, name): 19 | """Initialize logger instances.""" 20 | formatter = logging.Formatter( 21 | "%(asctime)s %(name)s %(levelname)s %(threadName)-10s %(message)s" 22 | ) 23 | 24 | logger = logging.getLogger(name) 25 | logger.setLevel(logging.DEBUG) 26 | 27 | filename = "{0}.log".format(datetime.today().strftime("%Y_%m_%d@%H_%M_%S")) 28 | 29 | if os.name != "nt": 30 | filepath = f"/var/log/{filename}" 31 | else: 32 | folder = os.path.join( 33 | os.getenv("LOCALAPPDATA"), 34 | "{{ cookiecutter.project_name }}", 35 | "{{ cookiecutter.library_name }}", 36 | ) 37 | if not os.path.exists(folder): 38 | os.makedirs(folder) 39 | filepath = os.path.join(folder, filename) 40 | fh = logging.FileHandler(filepath) 41 | fh.setLevel(logging.DEBUG) 42 | fh.setFormatter(formatter) 43 | logger.addHandler(fh) 44 | 45 | ch = logging.StreamHandler() 46 | ch.setLevel(logging.INFO) 47 | ch.setFormatter(formatter) 48 | logger.addHandler(ch) 49 | 50 | return logger 51 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/{{cookiecutter.__project_name_slug}}/src/server.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | 5 | """ 6 | {{ cookiecutter.project_name }}. 7 | 8 | {{ cookiecutter.library_name }} 9 | """ 10 | from fastapi import FastAPI 11 | 12 | from _version import __version__ 13 | from observability.logger import Logger 14 | 15 | logger = Logger.init("{{ cookiecutter.__project_name_slug }}") 16 | 17 | tags_metadata = [ 18 | { 19 | "name": "{{ cookiecutter.library_name }}", 20 | "description": "{{ cookiecutter.short_description }}", 21 | }, 22 | ] 23 | app = FastAPI( 24 | title="{{ cookiecutter.project_name }} {{ cookiecutter.library_name }} Application", 25 | openapi_tags=tags_metadata, 26 | debug=False, 27 | ) 28 | 29 | 30 | @app.get("/health") 31 | async def health(): 32 | """Check integrity of the server.""" 33 | return "The {{ cookiecutter.library_name }} API server is healthy." 34 | 35 | 36 | @app.get("/version") 37 | async def version(): 38 | """Check current version.""" 39 | return {"version": __version__} 40 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/{{cookiecutter.__project_name_slug}}/tests/conftest.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {%- endif %} 4 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/{{cookiecutter.__project_name_slug}}/tests/test_metadata.py: -------------------------------------------------------------------------------- 1 | from src import __version__ 2 | 3 | 4 | def test_pkg_version(): 5 | assert __version__ == "{{ cookiecutter.__version }}" 6 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_fastapi/{{cookiecutter.__project_name_slug}}/tests/test_server.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | from fastapi.testclient import TestClient 5 | 6 | from src._version import __version__ 7 | from src.server import app 8 | 9 | 10 | class TestServer: 11 | def setup_class(self): 12 | self.client = TestClient(app) 13 | 14 | def test_get_version(self): 15 | response = self.client.get("/version") 16 | assert response.status_code == 200 17 | assert response.json() == {"version": __version__} 18 | 19 | def test_get_health_status(self): 20 | response = self.client.get("/health") 21 | assert response.status_code == 200 22 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "__template_name": "pyace-flask", 3 | "project_name": "project", 4 | "__project_name_slug": "{{ cookiecutter.project_name | slugify(separator=('_')) }}", 5 | "library_name": "library", 6 | "ci_cd_platform": ["GitHub", "Azure DevOps"], 7 | "enable_docker": ["No", "Yes"], 8 | "enable_full_observability_stack": ["No", "Yes"], 9 | "copyright": "None", 10 | "__default_copyright": "{{ cookiecutter.copyright }}", 11 | "__library_name_slug": "{{ cookiecutter.library_name | slugify(separator=('_')) }}", 12 | "__pkg_name": "{{ cookiecutter.__project_name_slug | replace('_', '-') }}-{{ cookiecutter.__library_name_slug | replace('_', '-') }}", 13 | "__pkg_namespace": "src", 14 | "version": "0.1.dev0", 15 | "__version": "{{ cookiecutter.version }}", 16 | "short_description": "A {{ cookiecutter.project_name }} Python project for {{ cookiecutter.project_name }} {{ cookiecutter.library_name }}", 17 | "__short_description": "{{ cookiecutter.short_description }}", 18 | "repository_url": "https://github.com/ansys/{{ cookiecutter.__project_name_slug }}", 19 | "__repository_url": "{{ cookiecutter.repository_url }}", 20 | "__documentation_url": "", 21 | "requires_python": ["3.9", "3.10", "3.11", "3.12"], 22 | "__requires_python": "{{ cookiecutter.requires_python }}", 23 | "build_system": "setuptools", 24 | "__build_system": "setuptools", 25 | "logo": ["Ansys", "PyAnsys"], 26 | "__logo": "{{ cookiecutter.logo | lower }}", 27 | "logo_color": ["white", "black"], 28 | "__logo_color": "{{ cookiecutter.logo_color }}", 29 | "max_linelength": "100", 30 | "__max_linelength": "{{ cookiecutter.max_linelength }}", 31 | "__coverage_source": "", 32 | "__product_name_slug": "", 33 | "__is_pyansys": "False" 34 | } 35 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/hooks/post_gen_project.py: -------------------------------------------------------------------------------- 1 | """Post-processing script for cleaning the raw rendered project.""" 2 | import os 3 | import shutil 4 | from pathlib import Path 5 | 6 | import isort 7 | 8 | from ansys.templates.utils import keep_files 9 | 10 | DESIRED_STRUCTURE = [ 11 | "AUTHORS", 12 | "CHANGELOG.md", 13 | "CODE_OF_CONDUCT.md", 14 | "CONTRIBUTING.md", 15 | "CONTRIBUTORS.md", 16 | "doc/changelog.d/changelog_template.jinja", 17 | "doc/Makefile", 18 | "doc/make.bat", 19 | "doc/.vale.ini", 20 | "doc/styles/.gitignore", 21 | "doc/styles/config/vocabularies/ANSYS/accept.txt", 22 | "doc/styles/config/vocabularies/ANSYS/reject.txt", 23 | "doc/source/changelog.rst", 24 | "doc/source/conf.py", 25 | "doc/source/examples.rst", 26 | "doc/source/getting_started/index.rst", 27 | "doc/source/index.rst", 28 | "doc/source/_static/README.md", 29 | "doc/source/_templates/README.md", 30 | "examples/README.md", 31 | ".flake8", 32 | ".gitattributes", 33 | ".gitignore", 34 | "LICENSE", 35 | ".pre-commit-config.yaml", 36 | "pyproject.toml", 37 | "README.rst", 38 | "requirements/requirements_build.txt", 39 | "requirements/requirements_doc.txt", 40 | "requirements/requirements_tests.txt", 41 | "setup.py", 42 | "src/__init__.py", 43 | "src/_version.py", 44 | "src/server.py", 45 | "src/blueprints/__init__.py", 46 | "src/blueprints/health.py", 47 | "src/blueprints/version.py", 48 | "src/models/__init__.py", 49 | "src/observability/__init__.py", 50 | "src/observability/logger.py", 51 | "src/static/swagger.json", 52 | "tests/test_metadata.py", 53 | "tests/test_server.py", 54 | "tests/conftest.py", 55 | "tox.ini" 56 | ] 57 | """A list holding all desired files to be included in the project.""" 58 | 59 | 60 | def main(): 61 | """Entry point of the script.""" 62 | # Get baked project location path 63 | project_path = Path(os.getcwd()) 64 | 65 | # Move all requirements files into a requirements/ directory 66 | os.mkdir(project_path / "requirements") 67 | requirements_files = [ 68 | f"requirements_{name}.txt" for name in ["build", "doc", "tests"] 69 | ] 70 | for file in requirements_files: 71 | shutil.move(str(project_path / file), str(project_path / "requirements")) 72 | 73 | # Apply isort with desired config 74 | isort_config = isort.settings.Config( 75 | line_length="{{ cookiecutter.__max_linelength }}", 76 | profile="black", 77 | ) 78 | filepaths_list = [ 79 | project_path / "doc/source/conf.py", 80 | ] 81 | for filepath in filepaths_list: 82 | isort.api.sort_file(filepath, isort_config) 83 | 84 | # Remove ci/cd non-desired files 85 | ci_cd = "{{ cookiecutter.ci_cd_platform }}" 86 | if ci_cd == 'GitHub': 87 | DESIRED_STRUCTURE.extend( 88 | [ 89 | ".github/dependabot.yml", 90 | ".github/labeler.yml", 91 | ".github/labels.yml", 92 | ".github/workflows/ci_cd.yml", 93 | ".github/workflows/label.yml", 94 | ] 95 | ) 96 | if ci_cd == 'Azure DevOps': 97 | DESIRED_STRUCTURE.append("azure-pipeline.yml") 98 | 99 | # Remove docker non desired files 100 | enable_docker = "{{ cookiecutter.enable_docker }}" 101 | if enable_docker == 'Yes': 102 | DESIRED_STRUCTURE.append("docker/compose.yaml") 103 | DESIRED_STRUCTURE.append("docker/Dockerfile") 104 | DESIRED_STRUCTURE.append("docker/Docker.md") 105 | DESIRED_STRUCTURE.append(".dockerignore") 106 | 107 | # Remove non-desired files 108 | keep_files(DESIRED_STRUCTURE) 109 | 110 | 111 | if __name__ == "__main__": 112 | main() 113 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # --------------------------- 2 | FROM python:{{ cookiecutter.requires_python }}-slim AS base 3 | 4 | ENV PYTHONDONTWRITEBYTECODE=1 5 | ENV PYTHONUNBUFFERED=1 6 | 7 | RUN apt-get update \ 8 | && apt-get install -y \ 9 | && rm -rf /var/lib/apt/lists/* 10 | 11 | WORKDIR /app 12 | 13 | COPY requirements/requirements_build.txt . 14 | 15 | RUN pip install --no-cache-dir --upgrade pip && \ 16 | pip install --no-cache-dir -r requirements_build.txt 17 | 18 | # --------------------------- 19 | FROM base AS test 20 | 21 | COPY requirements/requirements_tests.txt . 22 | 23 | RUN pip install --no-cache-dir -r requirements_test.txt 24 | 25 | COPY . . 26 | 27 | RUN pytest tests 28 | 29 | # --------------------------- 30 | FROM base AS final 31 | LABEL org.opencontainers.image.authors={{ cookiecutter.__project_name_slug }} 32 | 33 | EXPOSE 5000 34 | 35 | COPY src . 36 | 37 | ENTRYPOINT [ "python", "server.py" ] -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/docker/compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3.9' 2 | 3 | services: 4 | {{ cookiecutter.library_name }}-api: 5 | image: {{ cookiecutter.__project_name_slug }}/{{ cookiecutter.__library_name_slug }}-api 6 | build: 7 | context: .. 8 | dockerfile: ./docker/Dockerfile 9 | ports: 10 | - "5000:5000" 11 | networks: 12 | - {{ cookiecutter.__project_name_slug }} 13 | 14 | {% if cookiecutter.enable_full_observability_stack == 'Yes' -%} 15 | 16 | # OPENTELEMETRY COLLECTOR 17 | 18 | otel-collector: 19 | image: otel/opentelemetry-collector-contrib:0.55.0 20 | command: [ "--config=/etc/otel-collector-config.yaml" ] 21 | volumes: 22 | - ./_deploy/otel-collector-config.yaml:/etc/otel-collector-config.yaml 23 | - /mnt/{{ cookiecutter.__project_name_slug }}/AppData/Local/Otel:/etc/output:rw # Store the logs 24 | ports: 25 | - "8888:8888" # Prometheus metrics exposed by the collector 26 | - "8889:8889" # Prometheus exporter metrics 27 | - "4317:4317" # OTLP gRPC receiver 28 | - "13133:13133" # Health check 29 | networks: 30 | - {{ cookiecutter.__project_name_slug }} 31 | {% endif %} 32 | 33 | 34 | 35 | networks: 36 | {{ cookiecutter.__project_name_slug }}: 37 | name: {{ cookiecutter.__project_name_slug }}-stream 38 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/requirements_build.txt: -------------------------------------------------------------------------------- 1 | build>=0.7.0 2 | flask 3 | flask-cors 4 | flask-swagger-ui 5 | twine>=3.8 6 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/requirements_tests.txt: -------------------------------------------------------------------------------- 1 | coverage==6.2 2 | docker 3 | pytest>=7.1.0 4 | pytest-cov>=3.0.0 5 | pytest-flakes==4.0.5 6 | pytest-pep8 7 | pytest-pythonpath 8 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/src/__init__.py: -------------------------------------------------------------------------------- 1 | """{{ cookiecutter.__project_name_slug }}.""" 2 | {%- if cookiecutter.copyright != "None" %} 3 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 4 | {% endif %} 5 | 6 | import os 7 | import sys 8 | 9 | from ._version import __version__ 10 | 11 | sys.path.append(os.path.join(os.path.dirname(__file__))) 12 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/src/_version.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | __version__ = "{{ cookiecutter.__version }}" 5 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/src/blueprints/__init__.py: -------------------------------------------------------------------------------- 1 | """Blueprints module.""" 2 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/src/blueprints/health.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | """ 5 | {{ cookiecutter.project_name }}. 6 | 7 | {{ cookiecutter.library_name }} 8 | """ 9 | 10 | from flask import Blueprint, jsonify 11 | 12 | from observability.logger import Logger 13 | 14 | blueprint = Blueprint("health_check", __name__, url_prefix="/api/health") 15 | 16 | logger = Logger.init("{{ cookiecutter.__project_name_slug }}") 17 | 18 | 19 | @blueprint.route("/") 20 | def health_check(): 21 | """Check health status.""" 22 | logger.info("Health check") 23 | return jsonify({"status": "ok"}) 24 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/src/blueprints/version.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | """ 5 | {{ cookiecutter.project_name }}. 6 | 7 | {{ cookiecutter.library_name }} 8 | """ 9 | 10 | from flask import Blueprint, jsonify 11 | 12 | from _version import __version__ 13 | 14 | blueprint = Blueprint("api_version", __name__, url_prefix="/api/version") 15 | 16 | 17 | @blueprint.route("/") 18 | def get_version(): 19 | """Get current version.""" 20 | return jsonify({"version": __version__}) 21 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/src/models/__init__.py: -------------------------------------------------------------------------------- 1 | """Models module.""" 2 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/src/observability/__init__.py: -------------------------------------------------------------------------------- 1 | """Observability module.""" 2 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/src/observability/logger.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | """ 5 | {{ cookiecutter.project_name }}. 6 | 7 | {{ cookiecutter.library_name }} 8 | """ 9 | from datetime import datetime 10 | import logging 11 | import os 12 | 13 | 14 | class Logger(object): 15 | """Logger class.""" 16 | 17 | @classmethod 18 | def init(cls, name): 19 | """Initialize instances for the Logger class.""" 20 | formatter = logging.Formatter( 21 | "%(asctime)s %(name)s %(levelname)s %(threadName)-10s %(message)s" 22 | ) 23 | 24 | logger = logging.getLogger(name) 25 | logger.setLevel(logging.DEBUG) 26 | 27 | filename = "{0}.log".format(datetime.today().strftime("%Y_%m_%d@%H_%M_%S")) 28 | 29 | if os.name != "nt": 30 | filepath = f"/var/log/{filename}" 31 | else: 32 | folder = os.path.join( 33 | os.getenv("LOCALAPPDATA"), 34 | "{{ cookiecutter.project_name }}", 35 | "{{ cookiecutter.library_name }}", 36 | ) 37 | if not os.path.exists(folder): 38 | os.makedirs(folder) 39 | filepath = os.path.join(folder, filename) 40 | fh = logging.FileHandler(filepath) 41 | fh.setLevel(logging.DEBUG) 42 | fh.setFormatter(formatter) 43 | logger.addHandler(fh) 44 | 45 | ch = logging.StreamHandler() 46 | ch.setLevel(logging.INFO) 47 | ch.setFormatter(formatter) 48 | logger.addHandler(ch) 49 | 50 | return logger 51 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/src/server.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | 5 | """ 6 | {{ cookiecutter.project_name }}. 7 | 8 | {{ cookiecutter.library_name }} 9 | """ 10 | import argparse 11 | 12 | from flask import Flask 13 | from flask_cors import CORS 14 | from flask_swagger_ui import get_swaggerui_blueprint 15 | 16 | from blueprints.health import blueprint as health_endpoint 17 | from blueprints.version import blueprint as version_endpoint 18 | from observability.logger import Logger 19 | 20 | SWAGGER_URL = "/api/docs" 21 | API_URL = "/static/swagger.json" 22 | 23 | 24 | SWAGGER_UI_BLUEPRINT = get_swaggerui_blueprint( 25 | SWAGGER_URL, 26 | API_URL, 27 | config={"app_name": "{{ cookiecutter.project_name }} {{ cookiecutter.library_name }} Api"}, 28 | ) 29 | 30 | logger = Logger.init("{{ cookiecutter.__project_name_slug }}") 31 | 32 | 33 | def create_app(): 34 | """Initialize the core application.""" 35 | app = Flask(__name__) 36 | CORS(app, resources=r"/api/*") 37 | app.config["CORS_HEADERS"] = "Content-Type" 38 | app.register_blueprint(version_endpoint) 39 | app.register_blueprint(health_endpoint) 40 | app.register_blueprint(SWAGGER_UI_BLUEPRINT, url_prefix=SWAGGER_URL) 41 | 42 | return app 43 | 44 | 45 | def serve(app, address, port, middleware=None): 46 | """Serve the application.""" 47 | if middleware is not None: 48 | middleware(app) 49 | 50 | logger.info("{{ cookiecutter.project_name }} {{ cookiecutter.library_name }} Server starting...") 51 | app.run(host=address, port=port) 52 | 53 | 54 | if __name__ == "__main__": 55 | app = create_app() 56 | logger.info("server.py main : parsing arguments") 57 | parser = argparse.ArgumentParser() 58 | parser.add_argument("--address", help="Set server address", default="0.0.0.0") 59 | parser.add_argument("-p", "--port", type=int, help="Set server port", default=5000) 60 | args = parser.parse_args() 61 | serve(app=app, address=args.address, port=args.port) 62 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/src/static/swagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "openapi": "3.0.0", 3 | "info": { 4 | "description": "{{ cookiecutter.short_description }}", 5 | "version": "1.0.0", 6 | "title": "{{ cookiecutter.project_name }} {{ cookiecutter.library_name }}", 7 | "contact": { 8 | "email": "" 9 | }, 10 | "license": { 11 | "name": "MIT", 12 | "url": "https://opensource.org/licenses/MIT" 13 | } 14 | }, 15 | "paths": { 16 | "/api/health": { 17 | "get": { 18 | "description": "Returns the health status of the api!", 19 | "responses": { 20 | "200": { 21 | "description": "Returns the health status", 22 | "schema": { 23 | "type": "string" 24 | } 25 | } 26 | } 27 | } 28 | }, 29 | "/api/version": { 30 | "get": { 31 | "description": "Returns the version of the api!", 32 | "responses": { 33 | "200": { 34 | "description": "Returns the version", 35 | "schema": { 36 | "type": "string" 37 | } 38 | } 39 | } 40 | } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/ansys-templates/02e0a89e89f8faae012183afc1ccadb897a95673/src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/tests/__init__.py -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/tests/conftest.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {%- endif %} 4 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/tests/test_metadata.py: -------------------------------------------------------------------------------- 1 | from src import __version__ 2 | 3 | 4 | def test_pkg_version(): 5 | assert __version__ == "{{ cookiecutter.__version }}" 6 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_flask/{{cookiecutter.__project_name_slug}}/tests/test_server.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | 5 | import json 6 | import multiprocessing 7 | import random 8 | 9 | import requests 10 | 11 | from src.server import create_app 12 | 13 | 14 | class TestServer: 15 | def setup_class(self): 16 | port = random.randint(5000, 10000) 17 | self.base_url = "http://127.0.0.1:" + str(port) 18 | app = create_app() 19 | self.server_proc = multiprocessing.Process(target=app.run, args=["127.0.0.1", port, False]) 20 | self.server_proc.start() 21 | 22 | def teardown_class(self): 23 | self.server_proc.terminate() 24 | self.server_proc.join() 25 | 26 | def test_get_version(self): 27 | response = requests.get(self.base_url + "/api/version", timeout=3) 28 | assert response.status_code == 200 29 | 30 | def test_get_health_status(self): 31 | response = requests.get(self.base_url + "/api/health", timeout=3) 32 | assert response.status_code == 200 33 | assert json.loads(response.content)["status"] == "ok" 34 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "__template_name": "pyace-grpc", 3 | "project_name": "project", 4 | "__project_name_slug": "{{ cookiecutter.project_name | slugify(separator=('_')) }}", 5 | "library_name": "library", 6 | "ci_cd_platform": ["GitHub", "Azure DevOps"], 7 | "enable_docker": ["No", "Yes"], 8 | "enable_full_observability_stack": ["No", "Yes"], 9 | "copyright": "None", 10 | "__default_copyright": "{{ cookiecutter.copyright }}", 11 | "__library_name_slug": "{{ cookiecutter.library_name | slugify(separator=('_')) }}", 12 | "__pkg_name": "{{ cookiecutter.__project_name_slug | replace('_', '-') }}-{{ cookiecutter.__library_name_slug | replace('_', '-') }}", 13 | "__pkg_namespace": "src", 14 | "version": "0.1.dev0", 15 | "__version": "{{ cookiecutter.version }}", 16 | "short_description": "A {{ cookiecutter.project_name }} Python project for {{ cookiecutter.project_name }} {{ cookiecutter.library_name }}", 17 | "__short_description": "{{ cookiecutter.short_description }}", 18 | "repository_url": "https://github.com/ansys/{{ cookiecutter.__project_name_slug }}", 19 | "__repository_url": "{{ cookiecutter.repository_url }}", 20 | "__documentation_url": "", 21 | "requires_python": ["3.9", "3.10", "3.11", "3.12"], 22 | "__requires_python": "{{ cookiecutter.requires_python }}", 23 | "build_system": "setuptools", 24 | "__build_system": "setuptools", 25 | "logo": ["Ansys", "PyAnsys"], 26 | "__logo": "{{ cookiecutter.logo | lower }}", 27 | "logo_color": ["white", "black"], 28 | "__logo_color": "{{ cookiecutter.logo_color }}", 29 | "max_linelength": "100", 30 | "__max_linelength": "{{ cookiecutter.max_linelength }}", 31 | "__coverage_source": "", 32 | "__product_name_slug": "", 33 | "__is_pyansys": "False" 34 | } 35 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/hooks/post_gen_project.py: -------------------------------------------------------------------------------- 1 | """Post-processing script for cleaning the raw rendered project.""" 2 | import os 3 | import shutil 4 | from pathlib import Path 5 | 6 | import isort 7 | 8 | from ansys.templates.utils import keep_files 9 | 10 | DESIRED_STRUCTURE = [ 11 | "AUTHORS", 12 | "CHANGELOG.md", 13 | "CODE_OF_CONDUCT.md", 14 | "CONTRIBUTING.md", 15 | "CONTRIBUTORS.md", 16 | "doc/changelog.d/changelog_template.jinja", 17 | "doc/Makefile", 18 | "doc/make.bat", 19 | "doc/.vale.ini", 20 | "doc/styles/.gitignore", 21 | "doc/styles/config/vocabularies/ANSYS/accept.txt", 22 | "doc/styles/config/vocabularies/ANSYS/reject.txt", 23 | "doc/source/changelog.rst", 24 | "doc/source/conf.py", 25 | "doc/source/examples.rst", 26 | "doc/source/getting_started/index.rst", 27 | "doc/source/index.rst", 28 | "doc/source/_static/README.md", 29 | "doc/source/_templates/README.md", 30 | "examples/README.md", 31 | ".flake8", 32 | ".gitattributes", 33 | ".gitignore", 34 | "LICENSE", 35 | ".pre-commit-config.yaml", 36 | "pyproject.toml", 37 | "README.rst", 38 | "requirements/requirements_build.txt", 39 | "requirements/requirements_doc.txt", 40 | "requirements/requirements_tests.txt", 41 | "protobufs/pingserver.proto", 42 | "setup.py", 43 | "src/__init__.py", 44 | "src/_version.py", 45 | "src/server.py", 46 | "src/client.py", 47 | "src/observability/logger.py", 48 | "src/services/__init__.py", 49 | "src/services/pinger.py", 50 | "src/stubs/__init__.py", 51 | "tests/test_metadata.py", 52 | "tox.ini", 53 | "protobufs/pingerserver.proto", 54 | "tests/test_server.py", 55 | "tests/conftest.py" 56 | ] 57 | """A list holding all desired files to be included in the project.""" 58 | 59 | 60 | def main(): 61 | """Entry point of the script.""" 62 | # Get baked project location path 63 | project_path = Path(os.getcwd()) 64 | 65 | # Move all requirements files into a requirements/ directory 66 | os.mkdir(project_path / "requirements") 67 | requirements_files = [ 68 | f"requirements_{name}.txt" for name in ["build", "doc", "tests"] 69 | ] 70 | for file in requirements_files: 71 | shutil.move(str(project_path / file), str(project_path / "requirements")) 72 | 73 | # Apply isort with desired config 74 | isort_config = isort.settings.Config( 75 | line_length="{{ cookiecutter.__max_linelength }}", 76 | profile="black", 77 | ) 78 | filepaths_list = [ 79 | project_path / "doc/source/conf.py", 80 | ] 81 | for filepath in filepaths_list: 82 | isort.api.sort_file(filepath, isort_config) 83 | 84 | # Remove ci/cd non-desired files 85 | ci_cd = "{{ cookiecutter.ci_cd_platform }}" 86 | if ci_cd == 'GitHub': 87 | DESIRED_STRUCTURE.extend( 88 | [ 89 | ".github/dependabot.yml", 90 | ".github/labeler.yml", 91 | ".github/labels.yml", 92 | ".github/workflows/ci_cd.yml", 93 | ".github/workflows/label.yml", 94 | ] 95 | ) 96 | if ci_cd == 'Azure DevOps': 97 | DESIRED_STRUCTURE.append("azure-pipeline.yml") 98 | 99 | # Remove docker non desired files 100 | enable_docker = "{{ cookiecutter.enable_docker }}" 101 | if enable_docker == 'Yes': 102 | DESIRED_STRUCTURE.append("docker/compose.yaml") 103 | DESIRED_STRUCTURE.append("docker/Dockerfile") 104 | DESIRED_STRUCTURE.append("docker/Docker.md") 105 | DESIRED_STRUCTURE.append(".dockerignore") 106 | 107 | # Remove non-desired files 108 | keep_files(DESIRED_STRUCTURE) 109 | 110 | 111 | if __name__ == "__main__": 112 | main() 113 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # --------------------------- 2 | FROM python:{{ cookiecutter.requires_python }}-slim AS base 3 | 4 | ENV PYTHONDONTWRITEBYTECODE=1 5 | ENV PYTHONUNBUFFERED=1 6 | 7 | RUN apt-get update \ 8 | && apt-get install -y \ 9 | && rm -rf /var/lib/apt/lists/* 10 | 11 | WORKDIR /app 12 | 13 | COPY requirements/requirements_build.txt . 14 | 15 | RUN pip install --no-cache-dir --upgrade pip && \ 16 | pip install --no-cache-dir -r requirements_build.txt 17 | 18 | RUN mkdir stubs 19 | 20 | ADD protobufs/ ./protobufs/ 21 | RUN python -m grpc_tools.protoc \ 22 | -I ./protobufs \ 23 | --python_out=./stubs \ 24 | --grpc_python_out=./stubs \ 25 | ./protobufs/*.proto 26 | 27 | # --------------------------- 28 | FROM base AS test 29 | 30 | COPY requirements/requirements_tests.txt . 31 | 32 | RUN pip install --no-cache-dir -r requirements_test.txt 33 | 34 | COPY . . 35 | 36 | RUN pytest tests 37 | 38 | # --------------------------- 39 | FROM base AS final 40 | LABEL org.opencontainers.image.authors={{ cookiecutter.__project_name_slug }} 41 | 42 | EXPOSE 50051 43 | 44 | COPY src . 45 | 46 | ENTRYPOINT [ "python", "server.py" ] -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/docker/compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3.9' 2 | 3 | services: 4 | {{ cookiecutter.library_name }}-grpc-api: 5 | image: {{ cookiecutter.__project_name_slug }}/{{ cookiecutter.__library_name_slug }}-grpc-api 6 | build: 7 | context: .. 8 | dockerfile: ./docker/Dockerfile 9 | ports: 10 | - "50051:50051" 11 | networks: 12 | - {{ cookiecutter.__project_name_slug }} 13 | 14 | {% if cookiecutter.enable_full_observability_stack == 'Yes' -%} 15 | 16 | # OPENTELEMETRY COLLECTOR 17 | 18 | otel-collector: 19 | image: otel/opentelemetry-collector-contrib:0.55.0 20 | command: [ "--config=/etc/otel-collector-config.yaml" ] 21 | volumes: 22 | - ./_deploy/otel-collector-config.yaml:/etc/otel-collector-config.yaml 23 | - /mnt/{{ cookiecutter.__project_name_slug }}/AppData/Local/Otel:/etc/output:rw # Store the logs 24 | ports: 25 | - "8888:8888" # Prometheus metrics exposed by the collector 26 | - "8889:8889" # Prometheus exporter metrics 27 | - "4317:4317" # OTLP gRPC receiver 28 | - "13133:13133" # Health check 29 | networks: 30 | - {{ cookiecutter.__project_name_slug }} 31 | {% endif %} 32 | 33 | 34 | 35 | networks: 36 | {{ cookiecutter.__project_name_slug }}: 37 | name: {{ cookiecutter.__project_name_slug }}-stream 38 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/protobufs/pingserver.proto: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | // Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | 5 | syntax = "proto3"; 6 | 7 | package pingserver; 8 | 9 | // The ping service definition. 10 | service Pinger { 11 | // Sends a ping to server 12 | rpc PingServer (EmptyRequest) returns (PingReply) {} 13 | 14 | rpc WhoPing (UserRequest) returns (PingReply) {} 15 | } 16 | 17 | 18 | message EmptyRequest { 19 | } 20 | // The request message containing the user's name. 21 | 22 | message UserRequest { 23 | string name = 1; 24 | } 25 | 26 | // The response message containing the greetings 27 | message PingReply { 28 | string message = 1; 29 | } 30 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/requirements_build.txt: -------------------------------------------------------------------------------- 1 | build>=0.7.0 2 | grpcio 3 | grpcio-tools 4 | twine>=3.8 5 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/requirements_tests.txt: -------------------------------------------------------------------------------- 1 | coverage==6.2 2 | docker 3 | pytest>=7.1.0 4 | pytest-cov>=3.0.0 5 | pytest-flakes==4.0.5 6 | pytest-grpc 7 | pytest-pep8 8 | pytest-pythonpath 9 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/src/__init__.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | """{{ cookiecutter.__project_name_slug }}.""" 5 | from ._version import __version__ 6 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/src/_version.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | __version__ = "{{ cookiecutter.__version }}" 5 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/src/client.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | 5 | """ 6 | {{ cookiecutter.project_name }}. 7 | 8 | {{ cookiecutter.library_name }} 9 | """ 10 | from __future__ import print_function 11 | 12 | import logging 13 | import os 14 | from pathlib import Path 15 | import sys 16 | 17 | import grpc 18 | 19 | sys.path.insert(0, os.path.join(Path(os.path.dirname(os.path.realpath(__file__))).parent, "stubs")) 20 | 21 | import stubs.pingserver_pb2 as pb2 22 | import stubs.pingserver_pb2_grpc as pb2_grpc 23 | 24 | 25 | def run(): 26 | """Run client.""" 27 | with grpc.insecure_channel("localhost:50051") as channel: 28 | stub = pb2_grpc.PingerStub(channel) 29 | response = stub.WhoPing(pb2.UserRequest(name="you")) 30 | print(response.message) 31 | 32 | 33 | if __name__ == "__main__": 34 | logging.basicConfig() 35 | run() 36 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/src/observability/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/ansys-templates/02e0a89e89f8faae012183afc1ccadb897a95673/src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/src/observability/__init__.py -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/src/observability/logger.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | """Logger module.""" 5 | 6 | from datetime import datetime 7 | import logging 8 | import os 9 | 10 | 11 | class Logger(object): 12 | """Logger class.""" 13 | 14 | @classmethod 15 | def init(cls, name): 16 | """Initialize logger instances.""" 17 | formatter = logging.Formatter( 18 | "%(asctime)s %(name)s %(levelname)s %(threadName)-10s %(message)s" 19 | ) 20 | 21 | logger = logging.getLogger(name) 22 | logger.setLevel(logging.DEBUG) 23 | 24 | filename = "{0}.log".format(datetime.today().strftime("%Y_%m_%d@%H_%M_%S")) 25 | 26 | if os.name != "nt": 27 | filepath = f"/var/log/{filename}" 28 | else: 29 | folder = os.path.join( 30 | os.getenv("LOCALAPPDATA"), 31 | "{{ cookiecutter.project_name }}", 32 | "{{ cookiecutter.library_name }}", 33 | ) 34 | if not os.path.exists(folder): 35 | os.makedirs(folder) 36 | filepath = os.path.join(folder, filename) 37 | fh = logging.FileHandler(filepath) 38 | fh.setLevel(logging.DEBUG) 39 | fh.setFormatter(formatter) 40 | logger.addHandler(fh) 41 | 42 | ch = logging.StreamHandler() 43 | ch.setLevel(logging.INFO) 44 | ch.setFormatter(formatter) 45 | logger.addHandler(ch) 46 | 47 | return logger 48 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/src/server.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | 5 | """ 6 | {{ cookiecutter.project_name }}. 7 | 8 | {{ cookiecutter.library_name }} 9 | """ 10 | from concurrent import futures 11 | 12 | import grpc 13 | 14 | from observability.logger import Logger 15 | from services.pinger import Pinger 16 | import stubs.pingserver_pb2_grpc 17 | 18 | 19 | def serve(): 20 | """Serve function.""" 21 | logger = Logger.init(__name__) 22 | port = 50051 23 | server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) 24 | stubs.pingserver_pb2_grpc.add_PingerServicer_to_server(Pinger(), server) 25 | logger.info(f"Server starting and listening on {port}") 26 | server.add_insecure_port(f"[::]:{port}") 27 | server.start() 28 | server.wait_for_termination() 29 | 30 | 31 | if __name__ == "__main__": 32 | serve() 33 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/src/services/__init__.py: -------------------------------------------------------------------------------- 1 | """Services module.""" 2 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/src/services/pinger.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | 5 | """ 6 | {{ cookiecutter.project_name }}. 7 | 8 | {{ cookiecutter.library_name }} 9 | """ 10 | from stubs.pingserver_pb2 import PingReply 11 | from stubs.pingserver_pb2_grpc import PingerServicer 12 | 13 | NumberPing = 0 14 | 15 | 16 | class Pinger(PingerServicer): 17 | """Pinger class.""" 18 | 19 | def PingServer(self, request, context): 20 | """Ping the server.""" 21 | global NumberPing 22 | NumberPing += 1 23 | return PingReply( 24 | message=f"Hello, the server is healthy and it had been pinged {NumberPing} times!" 25 | ) 26 | 27 | def WhoPing(self, request, context): 28 | """Check who ping the server.""" 29 | global NumberPing 30 | NumberPing += 1 31 | return PingReply(message=f"Hello, the server is pinged by {request.name}!") 32 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/src/stubs/__init__.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | 5 | """ 6 | {{ cookiecutter.project_name }}. 7 | 8 | {{ cookiecutter.library_name }} 9 | """ 10 | 11 | import os 12 | from pathlib import Path 13 | import sys 14 | 15 | sys.path.insert(0, os.path.join(Path(os.path.dirname(os.path.realpath(__file__))).parent, "stubs")) 16 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/ansys-templates/02e0a89e89f8faae012183afc1ccadb897a95673/src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/tests/__init__.py -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/tests/conftest.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | import pytest 5 | 6 | 7 | @pytest.fixture(scope="module") 8 | def grpc_add_to_server(): 9 | from src.stubs.pingserver_pb2_grpc import add_PingerServicer_to_server 10 | 11 | return add_PingerServicer_to_server 12 | 13 | 14 | @pytest.fixture(scope="module") 15 | def grpc_servicer(): 16 | from src.services.pinger import Pinger 17 | 18 | return Pinger() 19 | 20 | 21 | @pytest.fixture(scope="module") 22 | def grpc_stub_cls(grpc_channel): 23 | from src.stubs.pingserver_pb2_grpc import PingerStub 24 | 25 | return PingerStub 26 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/tests/test_metadata.py: -------------------------------------------------------------------------------- 1 | from src import __version__ 2 | 3 | 4 | def test_pkg_version(): 5 | assert __version__ == "{{ cookiecutter.__version }}" 6 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_grpc/{{cookiecutter.__project_name_slug}}/tests/test_server.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | import pytest 5 | 6 | from src.stubs.pingserver_pb2 import EmptyRequest, UserRequest 7 | 8 | 9 | @pytest.mark.smoke 10 | class TestServer: 11 | def test_first_ping(self, grpc_stub): 12 | request = EmptyRequest() 13 | response = grpc_stub.PingServer(request) 14 | assert response.message == "Hello, the server is healthy and it had been pinged 1 times!" 15 | 16 | def test_who_ping(self, grpc_stub): 17 | request = UserRequest(name="you") 18 | response = grpc_stub.WhoPing(request) 19 | assert response.message == f"Hello, the server is pinged by {request.name}!" 20 | 21 | def test_third_ping(self, grpc_stub): 22 | request = EmptyRequest() 23 | response = grpc_stub.PingServer(request) 24 | assert response.message == "Hello, the server is healthy and it had been pinged 3 times!" 25 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_pkg/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "__template_name": "pyace-pkg", 3 | "project_name": "project", 4 | "__project_name_slug": "{{ cookiecutter.project_name | slugify(separator=('_')) }}", 5 | "library_name": "library", 6 | "__library_name_slug": "{{ cookiecutter.library_name | slugify(separator=('_')) }}", 7 | "ci_cd_platform": ["GitHub", "Azure DevOps"], 8 | "enable_docker": ["No", "Yes"], 9 | "enable_full_observability_stack": ["No", "Yes"], 10 | "copyright": "None", 11 | "__default_copyright": "{{ cookiecutter.copyright }}", 12 | "__pkg_name": "{{ cookiecutter.__project_name_slug | replace('_', '-') }}-{{ cookiecutter.__library_name_slug | replace('_', '-') }}", 13 | "__pkg_namespace": "src", 14 | "version": "0.1.dev0", 15 | "__version": "{{ cookiecutter.version }}", 16 | "short_description": "A {{ cookiecutter.project_name }} Python project for {{ cookiecutter.project_name }} {{ cookiecutter.library_name }}", 17 | "__short_description": "{{ cookiecutter.short_description }}", 18 | "repository_url": "https://github.com/ansys/{{ cookiecutter.__project_name_slug }}", 19 | "__repository_url": "{{ cookiecutter.repository_url }}", 20 | "__documentation_url": "", 21 | "requires_python": ["3.9", "3.10", "3.11", "3.12"], 22 | "__requires_python": "{{ cookiecutter.requires_python }}", 23 | "build_system": "setuptools", 24 | "__build_system": "setuptools", 25 | "logo": ["Ansys", "PyAnsys"], 26 | "__logo": "{{ cookiecutter.logo | lower }}", 27 | "logo_color": ["white", "black"], 28 | "__logo_color": "{{ cookiecutter.logo_color }}", 29 | "max_linelength": "100", 30 | "__max_linelength": "{{ cookiecutter.max_linelength }}", 31 | "__coverage_source": "", 32 | "__product_name_slug": "", 33 | "__is_pyansys": "False" 34 | } 35 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_pkg/hooks/post_gen_project.py: -------------------------------------------------------------------------------- 1 | """Post-processing script for cleaning the raw rendered project.""" 2 | import os 3 | import shutil 4 | from pathlib import Path 5 | 6 | import isort 7 | 8 | from ansys.templates.utils import keep_files 9 | 10 | DESIRED_STRUCTURE = [ 11 | "AUTHORS", 12 | "CHANGELOG.md", 13 | "CODE_OF_CONDUCT.md", 14 | "CONTRIBUTING.md", 15 | "CONTRIBUTORS.md", 16 | "doc/changelog.d/changelog_template.jinja", 17 | "doc/Makefile", 18 | "doc/make.bat", 19 | "doc/.vale.ini", 20 | "doc/styles/.gitignore", 21 | "doc/styles/config/vocabularies/ANSYS/accept.txt", 22 | "doc/styles/config/vocabularies/ANSYS/reject.txt", 23 | "doc/source/changelog.rst", 24 | "doc/source/conf.py", 25 | "doc/source/examples.rst", 26 | "doc/source/getting_started/index.rst", 27 | "doc/source/index.rst", 28 | "doc/source/_static/README.md", 29 | "doc/source/_templates/README.md", 30 | "examples/README.md", 31 | ".flake8", 32 | ".gitattributes", 33 | ".gitignore", 34 | "LICENSE", 35 | ".pre-commit-config.yaml", 36 | "pyproject.toml", 37 | "README.rst", 38 | "requirements/requirements_build.txt", 39 | "requirements/requirements_doc.txt", 40 | "requirements/requirements_tests.txt", 41 | "setup.py", 42 | "src/__init__.py", 43 | "src/logger.py", 44 | "src/main.py", 45 | "tests/test_metadata.py", 46 | "tox.ini", 47 | "tests/__init__.py", 48 | "tests/conftest.py" 49 | ] 50 | """A list holding all desired files to be included in the project.""" 51 | 52 | 53 | def main(): 54 | """Entry point of the script.""" 55 | # Get baked project location path 56 | project_path = Path(os.getcwd()) 57 | 58 | # Move all requirements files into a requirements/ directory 59 | os.mkdir(project_path / "requirements") 60 | requirements_files = [ 61 | f"requirements_{name}.txt" for name in ["build", "doc", "tests"] 62 | ] 63 | for file in requirements_files: 64 | shutil.move(str(project_path / file), str(project_path / "requirements")) 65 | 66 | # Apply isort with desired config 67 | isort_config = isort.settings.Config( 68 | line_length="{{ cookiecutter.__max_linelength }}", 69 | profile="black", 70 | ) 71 | filepaths_list = [ 72 | project_path / "doc/source/conf.py", 73 | ] 74 | for filepath in filepaths_list: 75 | isort.api.sort_file(filepath, isort_config) 76 | 77 | # Remove ci/cd non-desired files 78 | ci_cd = "{{ cookiecutter.ci_cd_platform }}" 79 | if ci_cd == 'GitHub': 80 | DESIRED_STRUCTURE.extend( 81 | [ 82 | ".github/dependabot.yml", 83 | ".github/labeler.yml", 84 | ".github/labels.yml", 85 | ".github/workflows/ci_cd.yml", 86 | ".github/workflows/label.yml", 87 | ] 88 | ) 89 | if ci_cd == 'Azure DevOps': 90 | DESIRED_STRUCTURE.append("azure-pipeline.yml") 91 | 92 | # Remove docker non desired files 93 | enable_docker = "{{ cookiecutter.enable_docker }}" 94 | if enable_docker == 'Yes': 95 | DESIRED_STRUCTURE.append("docker/compose.yaml") 96 | DESIRED_STRUCTURE.append("docker/Dockerfile") 97 | DESIRED_STRUCTURE.append("docker/Docker.md") 98 | DESIRED_STRUCTURE.append(".dockerignore") 99 | 100 | # Remove non-desired files 101 | keep_files(DESIRED_STRUCTURE) 102 | 103 | 104 | if __name__ == "__main__": 105 | main() 106 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_pkg/{{cookiecutter.__project_name_slug}}/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # --------------------------- 2 | FROM python:{{ cookiecutter.requires_python }}-slim AS base 3 | 4 | # Keeps Python from generating .pyc files in the container 5 | ENV PYTHONDONTWRITEBYTECODE=1 6 | 7 | # Turns off buffering for easier container logging 8 | ENV PYTHONUNBUFFERED=1 9 | 10 | RUN apt-get update \ 11 | && apt-get install -y \ 12 | && rm -rf /var/lib/apt/lists/* 13 | 14 | COPY requirements/requirements_build.txt ./ 15 | 16 | RUN pip install --no-cache-dir --upgrade pip && \ 17 | pip install --no-cache-dir -r requirements_build.txt 18 | 19 | WORKDIR /app 20 | 21 | # --------------------------- 22 | FROM base AS test 23 | 24 | COPY requirements/requirements_test.txt ./ 25 | 26 | RUN pip install --no-cache-dir -r requirements_test.txt 27 | 28 | COPY . . 29 | 30 | RUN pytest tests 31 | 32 | # --------------------------- 33 | FROM base AS final 34 | LABEL org.opencontainers.image.authors={{ cookiecutter.__project_name_slug }} 35 | 36 | COPY src . 37 | 38 | ENTRYPOINT [ "python", "main.py" ] -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_pkg/{{cookiecutter.__project_name_slug}}/docker/compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3.9' 2 | 3 | services: 4 | 5 | {{ cookiecutter.library_name }}: 6 | image: {{ cookiecutter.__project_name_slug }}/{{ cookiecutter.__library_name_slug }} 7 | build: 8 | context: .. 9 | dockerfile: ./docker/Dockerfile 10 | stdin_open: true 11 | tty: true 12 | networks: 13 | - {{ cookiecutter.__project_name_slug }} 14 | 15 | {% if cookiecutter.enable_full_observability_stack == 'Yes' -%} 16 | 17 | # OPENTELEMETRY COLLECTOR 18 | 19 | otel-collector: 20 | image: otel/opentelemetry-collector-contrib:0.55.0 21 | command: [ "--config=/etc/otel-collector-config.yaml" ] 22 | volumes: 23 | - ./_deploy/otel-collector-config.yaml:/etc/otel-collector-config.yaml 24 | - /mnt/{{ cookiecutter.__project_name_slug }}/AppData/Local/Otel:/etc/output:rw # Store the logs 25 | ports: 26 | - "8888:8888" # Prometheus metrics exposed by the collector 27 | - "8889:8889" # Prometheus exporter metrics 28 | - "4317:4317" # OTLP gRPC receiver 29 | - "13133:13133" # Health check 30 | networks: 31 | - {{ cookiecutter.__project_name_slug }} 32 | {% endif %} 33 | 34 | 35 | 36 | networks: 37 | {{ cookiecutter.__project_name_slug }}: 38 | name: {{ cookiecutter.__project_name_slug }}-stream -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_pkg/{{cookiecutter.__project_name_slug}}/src/__init__.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | """ 5 | {{ cookiecutter.project_name }}. 6 | 7 | {{ cookiecutter.library_name }} 8 | """ 9 | 10 | try: 11 | import importlib.metadata as importlib_metadata 12 | except ModuleNotFoundError: 13 | import importlib_metadata 14 | 15 | __version__ = importlib_metadata.version(__name__.replace(".", "-")) 16 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_pkg/{{cookiecutter.__project_name_slug}}/src/logger.py: -------------------------------------------------------------------------------- 1 | """Logger module.""" 2 | {% if cookiecutter.copyright != "None" -%} 3 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 4 | {% endif %} 5 | from datetime import datetime 6 | import logging 7 | import os 8 | 9 | 10 | class Logger(object): 11 | """Logger class.""" 12 | 13 | @classmethod 14 | def init(cls, name): 15 | """Initialize Logger instances.""" 16 | formatter = logging.Formatter( 17 | "%(asctime)s %(name)s %(levelname)s %(threadName)-10s %(message)s" 18 | ) 19 | 20 | logger = logging.getLogger(name) 21 | logger.setLevel(logging.DEBUG) 22 | 23 | filename = "{0}.log".format(datetime.today().strftime("%Y_%m_%d@%H_%M_%S")) 24 | 25 | if os.name != "nt": 26 | filepath = f"/var/log/{filename}" 27 | else: 28 | folder = os.path.join(os.getenv("LOCALAPPDATA"), "my_company", "library") 29 | if not os.path.exists(folder): 30 | os.makedirs(folder) 31 | filepath = os.path.join(folder, filename) 32 | fh = logging.FileHandler(filepath) 33 | fh.setLevel(logging.DEBUG) 34 | fh.setFormatter(formatter) 35 | logger.addHandler(fh) 36 | 37 | ch = logging.StreamHandler() 38 | ch.setLevel(logging.INFO) 39 | ch.setFormatter(formatter) 40 | logger.addHandler(ch) 41 | 42 | return logger 43 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_pkg/{{cookiecutter.__project_name_slug}}/src/main.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} 4 | 5 | """ 6 | {{ cookiecutter.project_name }}. 7 | 8 | {{ cookiecutter.library_name }} 9 | """ 10 | 11 | from datetime import datetime 12 | 13 | from logger import Logger 14 | 15 | logger = Logger.init("{{ cookiecutter.project_name }}.{{ cookiecutter.library_name }}") 16 | 17 | 18 | def get_date_and_time(): 19 | """Compute today's datetime.""" 20 | return datetime.today().strftime("%Y-%m-%d-%H:%M:%S") 21 | 22 | 23 | if __name__ == "__main__": 24 | logger.info(f"Hello! Welcome, we are {get_date_and_time()}") 25 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_pkg/{{cookiecutter.__project_name_slug}}/tests/__init__.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {% endif %} -------------------------------------------------------------------------------- /src/ansys/templates/python/pyace_pkg/{{cookiecutter.__project_name_slug}}/tests/conftest.py: -------------------------------------------------------------------------------- 1 | {%- if cookiecutter.copyright != "None" -%} 2 | # Copyright (c) {% now "utc", '%Y' %}, {{ cookiecutter.copyright }}. Unauthorised use, distribution or duplication is prohibited 3 | {%- endif %} 4 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "__template_name": "pyansys", 3 | "product_name": "Product", 4 | "__product_name_slug": "{{ cookiecutter.product_name | slugify(separator=('_')) }}", 5 | "library_name": "Library", 6 | "__library_name_slug": "{{ cookiecutter.library_name | slugify(separator=('_')) }}", 7 | "__project_name_slug": "py{{ cookiecutter.__product_name_slug | replace('_', '-') }}-{{ cookiecutter.__library_name_slug | replace('_', '-')}}", 8 | "__pkg_name": "ansys-{{ cookiecutter.__product_name_slug | replace('_', '-') }}-{{ cookiecutter.__library_name_slug | replace('_', '-') }}", 9 | "__pkg_namespace": "ansys.{{ cookiecutter.__product_name_slug }}.{{ cookiecutter.__library_name_slug }}", 10 | "version": "0.1.dev0", 11 | "__version": "{{ cookiecutter.version }}", 12 | "short_description": "A Python wrapper for Ansys {{ cookiecutter.product_name }} {{ cookiecutter.library_name }}", 13 | "__short_description": "{{ cookiecutter.short_description | capitalize }}", 14 | "repository_url": "https://github.com/ansys/{{ cookiecutter.__project_name_slug }}", 15 | "__repository_url": "{{ cookiecutter.repository_url }}", 16 | "__documentation_url": "", 17 | "requires_python": ["3.9", "3.10", "3.11", "3.12"], 18 | "build_system": "setuptools", 19 | "__build_system": "setuptools", 20 | "__requires_python": "{{ cookiecutter.requires_python }}", 21 | "__logo": "pyansys", 22 | "__logo_color": "black", 23 | "max_linelength": "100", 24 | "__max_linelength": "{{ cookiecutter.max_linelength }}", 25 | "__coverage_source": "ansys.{{ cookiecutter.__product_name_slug }}", 26 | "__is_pyansys": "True" 27 | } 28 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys/hooks/post_gen_project.py: -------------------------------------------------------------------------------- 1 | from ansys.templates.utils import keep_files 2 | 3 | DESIRED_STRUCTURE = [ 4 | ".coveragerc", 5 | ".flake8", 6 | ".gitattributes", 7 | ".gitignore", 8 | ".pre-commit-config.yaml", 9 | "AUTHORS", 10 | "CHANGELOG.md", 11 | "CODE_OF_CONDUCT.md", 12 | "CONTRIBUTING.md", 13 | "CONTRIBUTORS.md", 14 | "doc/Makefile", 15 | "doc/make.bat", 16 | "doc/.vale.ini", 17 | "doc/styles/.gitignore", 18 | "doc/styles/config/vocabularies/ANSYS/accept.txt", 19 | "doc/styles/config/vocabularies/ANSYS/reject.txt", 20 | "doc/source/changelog.rst", 21 | "doc/source/conf.py", 22 | "doc/source/examples.rst", 23 | "doc/source/getting_started/index.rst", 24 | "doc/source/index.rst", 25 | "doc/source/_static/README.md", 26 | "doc/source/_templates/README.md", 27 | "examples/README.md", 28 | "LICENSE", 29 | "pyproject.toml", 30 | "README.rst", 31 | "requirements_build.txt", 32 | "requirements_doc.txt", 33 | "requirements_tests.txt", 34 | "setup.py", 35 | "src/ansys/{{ cookiecutter.__product_name_slug }}/{{ cookiecutter.__library_name_slug }}/__init__.py", 36 | "tests/test_metadata.py", 37 | ] 38 | """A list holding all desired files to be included in the project.""" 39 | 40 | 41 | def main(): 42 | """Entry point of the script.""" 43 | # Apply the desired structure to the project 44 | keep_files(DESIRED_STRUCTURE) 45 | 46 | if __name__ == "__main__": 47 | main() 48 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys/{{cookiecutter.__project_name_slug}}/README.rst: -------------------------------------------------------------------------------- 1 | Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }} 2 | {{ '=' * (cookiecutter.__project_name_slug | length) }} 3 | 4 | {{ cookiecutter.short_description }} 5 | 6 | 7 | How to install 8 | -------------- 9 | 10 | At least two installation modes are provided: user and developer. 11 | 12 | For users 13 | ^^^^^^^^^ 14 | 15 | User installation can be performed by running: 16 | 17 | .. code:: bash 18 | 19 | python -m pip install {{ cookiecutter.__pkg_name }} 20 | 21 | For developers 22 | ^^^^^^^^^^^^^^ 23 | 24 | Installing Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }} in developer mode allows 25 | you to modify the source and enhance it. 26 | 27 | Before contributing to the project, please refer to the `PyAnsys Developer's guide`_. You will 28 | need to follow these steps: 29 | 30 | #. Start by cloning this repository: 31 | 32 | .. code:: bash 33 | 34 | git clone {{ cookiecutter.repository_url }} 35 | 36 | #. Create a fresh-clean Python environment and activate it. Refer to the 37 | official `venv`_ documentation if you require further information: 38 | 39 | .. code:: bash 40 | 41 | # Create a virtual environment 42 | python -m venv .venv 43 | 44 | # Activate it in a POSIX system 45 | source .venv/bin/activate 46 | 47 | # Activate it in Windows CMD environment 48 | .venv\Scripts\activate.bat 49 | 50 | # Activate it in Windows Powershell 51 | .venv\Scripts\Activate.ps1 52 | 53 | #. Make sure you have the latest version of `pip`_: 54 | 55 | .. code:: bash 56 | 57 | python -m pip install -U pip 58 | 59 | #. Install the project in editable mode: 60 | 61 | .. code:: bash 62 | 63 | python -m pip install --editable {{ cookiecutter.__pkg_name }} 64 | 65 | #. Install additional requirements (if needed): 66 | 67 | .. code:: bash 68 | 69 | python -m pip install -r requirements/requirements_build.txt 70 | python -m pip install -r requirements/requirements_doc.txt 71 | python -m pip install -r requirements/requirements_tests.txt 72 | 73 | #. Finally, verify your development installation by running: 74 | 75 | .. code:: bash 76 | 77 | python -m pip install -r requirements/requirements_tests.txt 78 | pytest tests -v 79 | 80 | 81 | Style and Testing 82 | ----------------- 83 | 84 | If required, you can always call the style commands (`black`_, `isort`_, 85 | `flake8`_...) or unit testing ones (`pytest`_) from the command line. However, 86 | this does not guarantee that your project is being tested in an isolated 87 | environment, which is another reason to consider using `tox`_. 88 | 89 | 90 | Documentation 91 | ------------- 92 | 93 | For building documentation, you can either run the usual rules provided in the 94 | `Sphinx`_ Makefile, such us: 95 | 96 | .. code:: bash 97 | 98 | python -m pip install -r requirements/requirements_doc.txt 99 | make -C doc/ html 100 | 101 | # subsequently open the documentation with (under Linux): 102 | open doc/html/index.html 103 | 104 | Distributing 105 | ------------ 106 | 107 | If you would like to create either source or wheel files, start by installing 108 | the building requirements: 109 | 110 | .. code:: bash 111 | 112 | python -m pip install -r requirements/requirements_build.txt 113 | 114 | Then, you can execute: 115 | 116 | .. code:: bash 117 | 118 | python -m build 119 | python -m twine check dist/* 120 | 121 | 122 | .. LINKS AND REFERENCES 123 | .. _black: https://github.com/psf/black 124 | .. _flake8: https://flake8.pycqa.org/en/latest/ 125 | .. _isort: https://github.com/PyCQA/isort 126 | .. _PyAnsys Developer's guide: https://dev.docs.pyansys.com/ 127 | .. _pre-commit: https://pre-commit.com/ 128 | .. _pytest: https://docs.pytest.org/en/stable/ 129 | .. _Sphinx: https://www.sphinx-doc.org/en/master/ 130 | .. _pip: https://pypi.org/project/pip/ 131 | .. _tox: https://tox.wiki/ 132 | .. _venv: https://docs.python.org/3/library/venv.html 133 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys/{{cookiecutter.__project_name_slug}}/src/ansys/{{cookiecutter.__product_name_slug}}/{{cookiecutter.__library_name_slug}}/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | {{ cookiecutter.product_name }}. 3 | 4 | {{ cookiecutter.library_name }} 5 | """ 6 | 7 | try: 8 | import importlib.metadata as importlib_metadata 9 | except ModuleNotFoundError: 10 | import importlib_metadata 11 | 12 | __version__ = importlib_metadata.version(__name__.replace(".", "-")) 13 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys_advanced/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "__template_name": "pyansys-advanced", 3 | "product_name": "product", 4 | "__product_name_slug": "{{ cookiecutter.product_name | slugify(separator=('_')) }}", 5 | "library_name": "library", 6 | "__library_name_slug": "{{ cookiecutter.library_name | slugify(separator=('_')) }}", 7 | "__project_name_slug": "py{{ cookiecutter.__product_name_slug | replace('_', '-') }}-{{ cookiecutter.__library_name_slug | replace('_', '-')}}", 8 | "__pkg_name": "ansys-{{ cookiecutter.__product_name_slug | replace('_', '-') }}-{{ cookiecutter.__library_name_slug | replace('_', '-') }}", 9 | "__pkg_namespace": "ansys.{{ cookiecutter.__product_name_slug }}.{{ cookiecutter.__library_name_slug }}", 10 | "version": "0.1.dev0", 11 | "__version": "{{ cookiecutter.version }}", 12 | "short_description": "A Python wrapper for Ansys {{ cookiecutter.product_name }} {{ cookiecutter.library_name }}", 13 | "__short_description": "{{ cookiecutter.short_description | capitalize }}", 14 | "repository_url": "https://github.com/ansys/{{ cookiecutter.__project_name_slug }}", 15 | "__repository_url": "{{ cookiecutter.repository_url }}", 16 | "documentation_url": "https://{{ cookiecutter.product_name }}.docs.pyansys.com", 17 | "__documentation_url": "{{ cookiecutter.documentation_url }}", 18 | "requires_python": ["3.9", "3.10", "3.11", "3.12"], 19 | "__requires_python": "{{ cookiecutter.requires_python }}", 20 | "build_system": ["flit", "poetry", "setuptools"], 21 | "__build_system": "{{ cookiecutter.build_system }}", 22 | "__logo": "pyansys", 23 | "__logo_color": "black", 24 | "max_linelength": "100", 25 | "__max_linelength": "{{ cookiecutter.max_linelength }}", 26 | "__coverage_source": "ansys.{{ cookiecutter.__product_name_slug }}", 27 | "__is_pyansys": "True" 28 | } 29 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys_advanced/hooks/post_gen_project.py: -------------------------------------------------------------------------------- 1 | """Post-processing script for cleaning the raw rendered project.""" 2 | import os 3 | import shutil 4 | from pathlib import Path 5 | 6 | import isort 7 | 8 | from ansys.templates.utils import keep_files, remove_file 9 | 10 | ALLOWED_BUILD_SYSTEMS = ["flit", "poetry", "setuptools"] 11 | """A list of all allowed build systems by the template.""" 12 | 13 | DESIRED_STRUCTURE = [ 14 | "AUTHORS", 15 | "CHANGELOG.md", 16 | "CODE_OF_CONDUCT.md", 17 | "CONTRIBUTING.md", 18 | "CONTRIBUTORS.md", 19 | "doc/changelog.d/changelog_template.jinja", 20 | "doc/Makefile", 21 | "doc/make.bat", 22 | "doc/.vale.ini", 23 | "doc/styles/.gitignore", 24 | "doc/styles/config/vocabularies/ANSYS/accept.txt", 25 | "doc/styles/config/vocabularies/ANSYS/reject.txt", 26 | "doc/source/conf.py", 27 | "doc/source/index.rst", 28 | "doc/source/_static/README.md", 29 | "doc/source/_templates/README.md", 30 | "doc/source/getting_started/index.rst", 31 | "doc/source/changelog.rst", 32 | "doc/source/examples.rst", 33 | "examples/README.md", 34 | ".flake8", 35 | ".github/dependabot.yml", 36 | ".github/labeler.yml", 37 | ".github/labels.yml", 38 | ".github/workflows/ci_cd.yml", 39 | ".github/workflows/label.yml", 40 | ".gitattributes", 41 | ".gitignore", 42 | "LICENSE", 43 | ".pre-commit-config.yaml", 44 | "pyproject.toml", 45 | "README.rst", 46 | "src/ansys/{{ cookiecutter.__product_name_slug }}/{{ cookiecutter.__library_name_slug }}/__init__.py", 47 | "tests/test_metadata.py", 48 | "tox.ini", 49 | ] 50 | """A list holding all desired files to be included in the project.""" 51 | 52 | def main(): 53 | """Entry point of the script.""" 54 | # Get baked project location path 55 | project_path = Path(os.getcwd()) 56 | 57 | # Get the desired build system 58 | build_system = "{{ cookiecutter.build_system }}" 59 | 60 | # Move all requirements files into a requirements/ directory 61 | requirements_files = [ 62 | f"requirements_{name}.txt" for name in ["build", "doc", "tests"] 63 | ] 64 | if build_system == "poetry": 65 | # Poetry required and extra dependencies are collected inside the 66 | # 'pyproject.toml' file. Thus, there is no need to have requirements 67 | # files 68 | for file in requirements_files: 69 | remove_file(file, project_path) 70 | else: 71 | os.mkdir(project_path / "requirements") 72 | for file in requirements_files: 73 | shutil.move(str(project_path / file), str(project_path / "requirements")) 74 | 75 | # Apply isort with desired config 76 | isort_config = isort.settings.Config( 77 | line_length="{{ cookiecutter.__max_linelength }}", 78 | profile="black", 79 | ) 80 | filepaths_list = [ 81 | project_path / "doc/source/conf.py", 82 | ] 83 | for filepath in filepaths_list: 84 | isort.api.sort_file(filepath, isort_config) 85 | 86 | # Remove non-desired files 87 | if build_system == "setuptools": 88 | DESIRED_STRUCTURE.append("setup.py") 89 | keep_files(DESIRED_STRUCTURE) 90 | 91 | 92 | if __name__ == "__main__": 93 | main() 94 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys_advanced/{{cookiecutter.__project_name_slug}}/README.rst: -------------------------------------------------------------------------------- 1 | Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }} 2 | {{ '=' * (cookiecutter.__project_name_slug | length) }} 3 | |pyansys| |python| |pypi| |GH-CI| |codecov| |MIT| |black| 4 | 5 | .. |pyansys| image:: https://img.shields.io/badge/Py-Ansys-ffc107.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABDklEQVQ4jWNgoDfg5mD8vE7q/3bpVyskbW0sMRUwofHD7Dh5OBkZGBgW7/3W2tZpa2tLQEOyOzeEsfumlK2tbVpaGj4N6jIs1lpsDAwMJ278sveMY2BgCA0NFRISwqkhyQ1q/Nyd3zg4OBgYGNjZ2ePi4rB5loGBhZnhxTLJ/9ulv26Q4uVk1NXV/f///////69du4Zdg78lx//t0v+3S88rFISInD59GqIH2esIJ8G9O2/XVwhjzpw5EAam1xkkBJn/bJX+v1365hxxuCAfH9+3b9/+////48cPuNehNsS7cDEzMTAwMMzb+Q2u4dOnT2vWrMHu9ZtzxP9vl/69RVpCkBlZ3N7enoDXBwEAAA+YYitOilMVAAAAAElFTkSuQmCC 6 | :target: https://docs.pyansys.com/ 7 | :alt: PyAnsys 8 | 9 | .. |python| image:: https://img.shields.io/pypi/pyversions/{{cookiecutter.__pkg_name}}?logo=pypi 10 | :target: https://pypi.org/project/{{cookiecutter.__pkg_name}}/ 11 | :alt: Python 12 | 13 | .. |pypi| image:: https://img.shields.io/pypi/v/{{cookiecutter.__pkg_name}}.svg?logo=python&logoColor=white 14 | :target: https://pypi.org/project/{{cookiecutter.__pkg_name}} 15 | :alt: PyPI 16 | 17 | .. |codecov| image:: https://codecov.io/gh/ansys/{{cookiecutter.__project_name_slug}}/branch/main/graph/badge.svg 18 | :target: https://codecov.io/gh/ansys/{{cookiecutter.__project_name_slug}} 19 | :alt: Codecov 20 | 21 | .. |GH-CI| image:: https://github.com/ansys/{{cookiecutter.__project_name_slug}}/actions/workflows/ci_cd.yml/badge.svg 22 | :target: https://github.com/ansys/{{cookiecutter.__project_name_slug}}/actions/workflows/ci_cd.yml 23 | :alt: GH-CI 24 | 25 | .. |MIT| image:: https://img.shields.io/badge/License-MIT-yellow.svg 26 | :target: https://opensource.org/licenses/MIT 27 | :alt: MIT 28 | 29 | .. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg?style=flat 30 | :target: https://github.com/psf/black 31 | :alt: Black 32 | 33 | 34 | Overview 35 | -------- 36 | 37 | {{ cookiecutter.short_description }} 38 | 39 | .. contribute_start 40 | 41 | Installation 42 | ^^^^^^^^^^^^ 43 | 44 | You can use `pip `_ to install Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }}. 45 | 46 | .. code:: bash 47 | 48 | pip install {{cookiecutter.__pkg_name}} 49 | 50 | To install the latest development version, run these commands: 51 | 52 | .. code:: bash 53 | 54 | git clone {{cookiecutter.__repository_url}} 55 | cd {{ cookiecutter.__project_name_slug }} 56 | pip install -e . 57 | 58 | For more information, see `Getting Started`_. 59 | 60 | Basic usage 61 | ^^^^^^^^^^^ 62 | 63 | This code shows how to import Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }} and use some basic capabilities: 64 | 65 | .. code:: python 66 | 67 | print("Put sample code here") 68 | 69 | For comprehensive usage information, see `Examples`_ in the `Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }} documentation`_. 70 | 71 | Documentation and issues 72 | ^^^^^^^^^^^^^^^^^^^^^^^^ 73 | Documentation for the latest stable release of Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }} is hosted at `Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }} documentation`_. 74 | 75 | In the upper right corner of the documentation's title bar, there is an option for switching from 76 | viewing the documentation for the latest stable release to viewing the documentation for the 77 | development version or previously released versions. 78 | 79 | On the `Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }} Issues <{{cookiecutter.__repository_url}}/issues>`_ page, 80 | you can create issues to report bugs and request new features. On the `Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }} Discussions 81 | <{{cookiecutter.__repository_url}}/discussions>`_ page or the `Discussions `_ 82 | page on the Ansys Developer portal, you can post questions, share ideas, and get community feedback. 83 | 84 | To reach the project support team, email `pyansys.core@ansys.com `_. 85 | 86 | 87 | .. LINKS AND REFERENCES 88 | .. _Getting Started: https://{{ cookiecutter.product_name }}.docs.pyansys.com/version/stable/getting_started/index.html 89 | .. _Examples: https://{{ cookiecutter.product_name }}.docs.pyansys.com/version/stable/examples.html 90 | .. _Py{{ cookiecutter.product_name }} {{ cookiecutter.library_name }} documentation: https://{{ cookiecutter.product_name }}.docs.pyansys.com/version/stable/index.html 91 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys_advanced/{{cookiecutter.__project_name_slug}}/src/ansys/{{cookiecutter.__product_name_slug}}/{{cookiecutter.__library_name_slug}}/__init__.py: -------------------------------------------------------------------------------- 1 | """{{ cookiecutter.product_name }}.{{ cookiecutter.library_name }} init file.""" 2 | 3 | import importlib.metadata as importlib_metadata 4 | 5 | __version__ = importlib_metadata.version(__name__.replace(".", "-")) 6 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys_openapi_client/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "__template_name": "pyansys-openapi-client", 3 | "product_name": "product", 4 | "__product_name_slug": "{{ cookiecutter.product_name | slugify(separator=('_')) }}", 5 | "library_name": "library", 6 | "__library_name_slug": "{{ cookiecutter.library_name | slugify(separator=('_')) }}", 7 | "__project_name_slug": "py{{ cookiecutter.__product_name_slug | replace('_', '-') }}-{{ cookiecutter.__library_name_slug | replace('_', '-')}}-openapi", 8 | "__pkg_name": "ansys-{{ cookiecutter.__product_name_slug | replace('_', '-') }}-{{ cookiecutter.__library_name_slug | replace('_', '-') }}-openapi", 9 | "__pkg_namespace": "ansys.{{ cookiecutter.__product_name_slug }}.{{ cookiecutter.__library_name_slug }}_openapi", 10 | "__wrapper_package_name": "ansys-{{ cookiecutter.__product_name_slug | replace('_', '-') }}-{{ cookiecutter.__library_name_slug | replace('_', '-') }}", 11 | "yaml_file_name": "library.yaml", 12 | "__yaml_file_name": "{{ cookiecutter.yaml_file_name }}", 13 | "version": "0.1.dev0", 14 | "__version": "{{ cookiecutter.version }}", 15 | "short_description": "Autogenerated client library for the {{ cookiecutter.product_name }} {{ cookiecutter.library_name }} library. Direct use of this package is unsupported, please use {{ cookiecutter.__wrapper_package_name }} instead.", 16 | "__short_description": "{{ cookiecutter.short_description | capitalize }}", 17 | "repository_url": "https://github.com/ansys/{{ cookiecutter.__project_name_slug }}", 18 | "__repository_url": "{{ cookiecutter.repository_url }}", 19 | "__documentation_url": "", 20 | "requires_python": ["3.9", "3.10", "3.11", "3.12"], 21 | "__requires_python": "{{ cookiecutter.requires_python }}", 22 | "build_system": "flit", 23 | "__build_system": "flit", 24 | "__logo": "", 25 | "__logo_color": "", 26 | "max_linelength": "100", 27 | "__max_linelength": "{{ cookiecutter.max_linelength }}", 28 | "__coverage_source": "ansys.{{ cookiecutter.__product_name_slug }}", 29 | "__is_pyansys": "True" 30 | } 31 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys_openapi_client/hooks/post_gen_project.py: -------------------------------------------------------------------------------- 1 | """Post-processing script for cleaning the raw rendered project.""" 2 | import os 3 | from pathlib import Path 4 | 5 | from ansys.templates.utils import keep_files 6 | 7 | ALLOWED_BUILD_SYSTEMS = ["flit"] 8 | """A list of all allowed build systems by the template.""" 9 | 10 | DESIRED_STRUCTURE = [ 11 | "AUTHORS", 12 | "CHANGELOG.md", 13 | "CODE_OF_CONDUCT.md", 14 | "CONTRIBUTING.md", 15 | "CONTRIBUTORS.md", 16 | ".flake8", 17 | ".github/workflows/build_and_test_library.yml", 18 | ".github/workflows/generate_library.yml", 19 | ".github/dependabot.yml", 20 | ".gitattributes", 21 | ".gitignore", 22 | "LICENSE", 23 | ".pre-commit-config.yaml", 24 | ".m2/settings.xml", 25 | "yaml/{{ cookiecutter.yaml_file_name }}", 26 | "pom.xml" 27 | ] 28 | """A list holding all desired files to be included in the project.""" 29 | 30 | 31 | def main(): 32 | """Entry point of the script.""" 33 | 34 | # Get baked project location path 35 | project_path = Path(os.getcwd()) 36 | 37 | # Get the desired build system 38 | build_system = "{{ cookiecutter.build_system }}" 39 | 40 | keep_files(DESIRED_STRUCTURE) 41 | 42 | 43 | if __name__ == "__main__": 44 | main() 45 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys_openapi_client/{{cookiecutter.__project_name_slug}}/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | 8 | updates: 9 | - package-ecosystem: "pip" 10 | directory: "/{{ cookiecutter.__pkg_name }}/" 11 | schedule: 12 | interval: "weekly" 13 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys_openapi_client/{{cookiecutter.__project_name_slug}}/.github/workflows/build_and_test_library.yml: -------------------------------------------------------------------------------- 1 | name: Build and Test Client Library 2 | on: 3 | push: 4 | tags: 5 | - "*" 6 | paths: 7 | - "{{ cookiecutter.__pkg_name }}/**" 8 | pull_request: 9 | paths: 10 | - "{{ cookiecutter.__pkg_name }}/**" 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | 19 | - name: Setup Python 20 | uses: actions/setup-python@v2 21 | with: 22 | python-version: 3.8 23 | 24 | - name: Install build requirements 25 | run: pip install flit 26 | 27 | - name: Create wheel 28 | working-directory: ansys-product-library-openapi 29 | run: flit build 30 | 31 | - name: Validate wheel 32 | working-directory: ansys-product-library-openapi 33 | run: | 34 | pip install twine 35 | twine check dist/* 36 | 37 | - name: Upload wheel artifact 38 | uses: actions/upload-artifact@v2 39 | with: 40 | name: {{ cookiecutter.__pkg_name }}-wheel 41 | path: {{ cookiecutter.__pkg_name }}/dist/ 42 | retention-days: 7 43 | 44 | test: 45 | name: Unit test on supported platforms 46 | runs-on: ubuntu-latest 47 | strategy: 48 | matrix: 49 | python-version: ['3.8', '3.9', '3.10' , '3.11'] 50 | steps: 51 | - uses: actions/checkout@v1 52 | 53 | - name: Set up Python {{ '${{ matrix.python-version }}' }} 54 | uses: actions/setup-python@v2 55 | with: 56 | python-version: {{ '${{ matrix.python-version }}' }} 57 | 58 | - name: Install dependencies 59 | run: | 60 | python -m pip install --upgrade pip 61 | pip install tox tox-gh-actions 62 | 63 | - name: Test with tox 64 | working-directory: {{ cookiecutter.__pkg_name }} 65 | run: | 66 | tox 67 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys_openapi_client/{{cookiecutter.__project_name_slug}}/.github/workflows/generate_library.yml: -------------------------------------------------------------------------------- 1 | name: Generate Library and Create PR 2 | 3 | on: 4 | push: 5 | tags: 6 | - "*" 7 | branches: 8 | - main 9 | paths: 10 | - 'yaml/{{ cookiecutter.__yaml_file_name }}' 11 | - 'pom.xml' 12 | - '.github/workflows/generate_library.yml' 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - name: Get Bot Application Token 20 | id: get_workflow_token 21 | uses: peter-murray/workflow-application-token-action@v1 22 | with: 23 | application_id: {{ '${{ secrets.BOT_APPLICATION_ID }}' }} 24 | application_private_key: {{ '${{ secrets.BOT_APPLICATION_PRIVATE_KEY }}' }} 25 | 26 | - uses: actions/checkout@v2 27 | with: 28 | token: {{ '${{ steps.get_workflow_token.outputs.token }}' }} 29 | 30 | - name: Set up JDK 11 31 | uses: actions/setup-java@v2 32 | with: 33 | java-version: '11' 34 | distribution: 'adopt' 35 | cache: maven 36 | 37 | - name: Clean library folder 38 | run: rm -rf {{ cookiecutter.__pkg_name }} 39 | 40 | - name: Build client library 41 | run: mvn -Dbuild-id={{ '${{ github.run_number }}' }} -s .m2/settings.xml compile 42 | env: 43 | MAVEN_OPTS: "-Dlog4j2.formatMsgNoLookups=true" 44 | SERVER_USERNAME: {{ '${{ secrets.REPO_USER }}' }} 45 | SERVER_PASSWORD: {{ '${{ secrets.REPO_TOKEN }}' }} 46 | 47 | - name: Create Pull Request 48 | uses: peter-evans/create-pull-request@v3 49 | with: 50 | commit-message: Update client library 51 | committer: GitHub 52 | author: {{ '${{ github.actor }}' }} <{{ '${{ github.actor }}' }}@users.noreply.github.com> 53 | signoff: false 54 | branch: client-library-build 55 | delete-branch: true 56 | token: {{ '${{ steps.get_workflow_token.outputs.token }}' }} 57 | title: 'Update client library' 58 | body: | 59 | Update library with new YAML interface definition 60 | labels: | 61 | automated 62 | team-reviewers: | 63 | Maintainers 64 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys_openapi_client/{{cookiecutter.__project_name_slug}}/.m2/settings.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | github 8 | 9 | 10 | 11 | 12 | github 13 | 14 | 15 | central 16 | https://repo1.maven.org/maven2 17 | 18 | 19 | github 20 | https://maven.pkg.github.com/pyansys/openapi-client-template 21 | 22 | true 23 | 24 | 25 | 26 | 27 | 28 | central 29 | https://repo1.maven.org/maven2 30 | 31 | 32 | github 33 | https://maven.pkg.github.com/pyansys/openapi-client-template 34 | 35 | true 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | github 45 | ${env.SERVER_USERNAME} 46 | ${env.SERVER_PASSWORD} 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pyansys_openapi_client/{{cookiecutter.__project_name_slug}}/yaml/{{ cookiecutter.yaml_file_name }}: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansys/ansys-templates/02e0a89e89f8faae012183afc1ccadb897a95673/src/ansys/templates/python/pyansys_openapi_client/{{cookiecutter.__project_name_slug}}/yaml/{{ cookiecutter.yaml_file_name }} -------------------------------------------------------------------------------- /src/ansys/templates/python/pybasic/cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "__template_name": "pybasic", 3 | "project_name": "", 4 | "__project_name_slug": "{{ cookiecutter.project_name | slugify(separator=('_')) }}", 5 | "version": "0.1.dev0", 6 | "__version": "{{ cookiecutter.version }}", 7 | "short_description": "", 8 | "__short_description": "{{ cookiecutter.short_description | capitalize }}", 9 | "__pkg_name": "{{ cookiecutter.__project_name_slug | replace('_', '-')}}", 10 | "__pkg_namespace": "{{ cookiecutter.__project_name_slug }}", 11 | "requires_python": ["3.9", "3.10", "3.11", "3.12"], 12 | "__requires_python": "{{ cookiecutter.requires_python }}", 13 | "repository_url": "", 14 | "__repository_url": "{{ cookiecutter.repository_url }}", 15 | "__documentation_url": "", 16 | "build_system": "setuptools", 17 | "__build_system": "setuptools", 18 | "max_linelength": "100", 19 | "__max_linelength": "{{ cookiecutter.max_linelength }}", 20 | "__logo": "pyansys", 21 | "__logo_color": "black", 22 | "__coverage_source": "{{ cookiecutter.__project_name_slug }}", 23 | "__product_name_slug": "", 24 | "__library_name_slug": "", 25 | "__is_pyansys": "False" 26 | } 27 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pybasic/hooks/post_gen_project.py: -------------------------------------------------------------------------------- 1 | from ansys.templates.utils import keep_files 2 | 3 | 4 | DESIRED_STRUCTURE = [ 5 | ".coveragerc", 6 | "AUTHORS", 7 | "CHANGELOG.md", 8 | "CODE_OF_CONDUCT.md", 9 | "CONTRIBUTING.md", 10 | "CONTRIBUTORS.md", 11 | "doc/Makefile", 12 | "doc/make.bat", 13 | "doc/.vale.ini", 14 | "doc/styles/.gitignore", 15 | "doc/styles/config/vocabularies/ANSYS/accept.txt", 16 | "doc/styles/config/vocabularies/ANSYS/reject.txt", 17 | "doc/source/changelog.rst", 18 | "doc/source/conf.py", 19 | "doc/source/examples.rst", 20 | "doc/source/getting_started/index.rst", 21 | "doc/source/index.rst", 22 | "doc/source/_static/README.md", 23 | "doc/source/_templates/README.md", 24 | "examples/README.md", 25 | ".flake8", 26 | ".gitattributes", 27 | ".gitignore", 28 | "LICENSE", 29 | "pyproject.toml", 30 | "README.rst", 31 | "requirements_build.txt", 32 | "requirements_doc.txt", 33 | "requirements_tests.txt", 34 | "setup.py", 35 | "src/{{ cookiecutter.__project_name_slug }}/__init__.py", 36 | "tests/test_metadata.py", 37 | ] 38 | """A list holding all desired files to be included in the project.""" 39 | 40 | 41 | def main(): 42 | """Entry point of the script.""" 43 | # Apply the desired structure to the project 44 | keep_files(DESIRED_STRUCTURE) 45 | 46 | if __name__ == "__main__": 47 | main() 48 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pybasic/{{cookiecutter.__project_name_slug}}/README.rst: -------------------------------------------------------------------------------- 1 | {{ cookiecutter.__project_name_slug }} 2 | {{ '=' * (cookiecutter.__project_name_slug | length) }} 3 | 4 | {{ cookiecutter.__short_description }} 5 | 6 | 7 | How to install 8 | -------------- 9 | 10 | At least two installation modes are provided: user and developer. 11 | 12 | For users 13 | ^^^^^^^^^ 14 | 15 | User installation can be performed by running: 16 | 17 | .. code:: bash 18 | 19 | python -m pip install {{ cookiecutter.__pkg_name }} 20 | 21 | For developers 22 | ^^^^^^^^^^^^^^ 23 | 24 | Before contributing to the project, please refer to the `PyAnsys Developer's 25 | guide`_. You will need to follow these steps: 26 | 27 | #. Start by cloning this repository: 28 | 29 | .. code:: bash 30 | 31 | git clone {{ cookiecutter.repository_url }} 32 | 33 | #. Create a fresh-clean Python environment and activate it. Refer to the 34 | official `venv`_ documentation if you require further information: 35 | 36 | .. code:: bash 37 | 38 | # Create a virtual environment 39 | python -m venv .venv 40 | 41 | # Activate it in a POSIX system 42 | source .venv/bin/activate 43 | 44 | # Activate it in Windows CMD environment 45 | .venv\Scripts\activate.bat 46 | 47 | # Activate it in Windows Powershell 48 | .venv\Scripts\Activate.ps1 49 | 50 | #. Make sure you have the latest version of `pip`_: 51 | 52 | .. code:: bash 53 | 54 | python -m pip install -U pip 55 | 56 | #. Install the project in editable mode: 57 | 58 | .. code:: bash 59 | 60 | python -m pip install --editable {{ cookiecutter.__pkg_name }} 61 | 62 | #. Install additional requirements (if needed): 63 | 64 | .. code:: bash 65 | 66 | python -m pip install -r requirements_build.txt 67 | python -m pip install -r requirements_doc.txt 68 | python -m pip install -r requirements_tests.txt 69 | 70 | 71 | #. Finally, verify your development installation by running: 72 | 73 | .. code:: bash 74 | 75 | python -m pip install -r requirements_tests.txt 76 | pytest tests -vv 77 | 78 | 79 | Style and Testing 80 | ----------------- 81 | 82 | If required, you can always call the style commands (`black`_, `isort`_, 83 | `flake8`_...) or unit testing ones (`pytest`_) from the command line. However, 84 | this does not guarantee that your project is being tested in an isolated 85 | environment, which is another reason to use tools like `tox`_. 86 | 87 | 88 | Documentation 89 | ------------- 90 | 91 | For building documentation, you can either run the usual rules provided in the 92 | `Sphinx`_ Makefile, such us: 93 | 94 | .. code:: bash 95 | 96 | python -m pip install -r requirements_doc.txt 97 | make -C doc/ html 98 | 99 | # optionally view the generated documentation (on linux) with 100 | open doc/html/index.html 101 | 102 | 103 | Distributing 104 | ------------ 105 | 106 | If you would like to create either source or wheel files, start by installing 107 | the building requirements: 108 | 109 | .. code:: bash 110 | 111 | python -m pip install -r requirements_build.txt 112 | 113 | Then, you can execute: 114 | 115 | .. code:: bash 116 | 117 | python -m build 118 | python -m twine check dist/* 119 | 120 | 121 | .. LINKS AND REFERENCES 122 | .. _black: https://github.com/psf/black 123 | .. _flake8: https://flake8.pycqa.org/en/latest/ 124 | .. _isort: https://github.com/PyCQA/isort 125 | .. _PyAnsys Developer's guide: https://dev.docs.pyansys.com/ 126 | .. _pre-commit: https://pre-commit.com/ 127 | .. _pytest: https://docs.pytest.org/en/stable/ 128 | .. _Sphinx: https://www.sphinx-doc.org/en/master/ 129 | .. _pip: https://pypi.org/project/pip/ 130 | .. _tox: https://tox.wiki/ 131 | .. _venv: https://docs.python.org/3/library/venv.html 132 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pybasic/{{cookiecutter.__project_name_slug}}/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name="{{ cookiecutter.__pkg_name }}", 5 | version="{{ cookiecutter.__version }}", 6 | url="{{ cookiecutter.__repository_url }}", 7 | author="ANSYS, Inc.", 8 | author_email="pyansys.support@ansys.com", 9 | maintainer="PyAnsys developers", 10 | maintainer_email="pyansys.core@ansys.com", 11 | classifiers=[ 12 | "Development Status :: 4 - Beta", 13 | "Programming Language :: Python :: 3", 14 | "License :: OSI Approved :: MIT License", 15 | "Operating System :: OS Independent", 16 | ], 17 | license="MIT", 18 | license_file="LICENSE", 19 | description="{{ cookiecutter.__short_description }}", 20 | long_description=open("README.rst").read(), 21 | install_requires=["importlib-metadata >=4.0"], 22 | python_requires=">={{ cookiecutter.__requires_python }}", 23 | packages=find_packages(where="src"), 24 | package_dir={"": "src"}, 25 | ) 26 | -------------------------------------------------------------------------------- /src/ansys/templates/python/pybasic/{{cookiecutter.__project_name_slug}}/src/{{cookiecutter.__project_name_slug}}/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | {{ cookiecutter.__pkg_name | replace('-', ' ') | title }}. 3 | """ 4 | 5 | try: 6 | import importlib.metadata as importlib_metadata 7 | except ModuleNotFoundError: 8 | import importlib_metadata 9 | 10 | __version__ = importlib_metadata.version(__name__.replace(".", "-")) 11 | -------------------------------------------------------------------------------- /src/ansys/templates/testing.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. 2 | # SPDX-License-Identifier: MIT 3 | # 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | """A collection of routines focused on testing.""" 24 | 25 | import os 26 | 27 | from ansys.templates.utils import bake_template 28 | 29 | 30 | def assert_template_baking_process(template_path, output_path, cookiecutter_vars): 31 | """ 32 | Assert if template renders properly. 33 | 34 | Parameters 35 | ---------- 36 | template_path : ~pathlib.Path 37 | Path to the project template. 38 | output_path : ~pathlib.Path 39 | Path to the output baked project. 40 | cookiecutter_vars : dict 41 | A dictionary holding cookiecutter variables and their values. 42 | 43 | """ 44 | bake_template( 45 | template_path, 46 | output_path, 47 | overwrite_if_exists=True, 48 | no_input=True, 49 | extra_context=cookiecutter_vars, 50 | ) 51 | 52 | 53 | def assert_file_in_baked_project(file, project_path): 54 | """ 55 | Assert if file is exists inside desired output path. 56 | 57 | Parameters 58 | ---------- 59 | file : str 60 | Expected file path relative to the output project path. 61 | project_path : ~pathlib.Path 62 | Path to the output project path. 63 | """ 64 | assert (project_path.joinpath(file)).is_file() 65 | 66 | 67 | def assert_files_in_baked_project(files_list, project_path): 68 | """ 69 | Assert if given files exists inside desired output path. 70 | 71 | Parameters 72 | ---------- 73 | files_list : list 74 | A list of expected files path relative to the output project path. 75 | project_path : ~pathlib.Path 76 | Path to the output project path. 77 | """ 78 | for file in files_list: 79 | assert_file_in_baked_project(file, project_path) 80 | 81 | def assert_project_structure(expected_structure, project_path): 82 | """Assert if project has desired structure. 83 | 84 | If any additional files are encountered in the rendered project, it will 85 | raise an AssertionError. 86 | 87 | Parameters 88 | ---------- 89 | expected_structure : list 90 | A list of expected files path relative to the output project path. 91 | project_path : ~pathlib.Path 92 | Path to the output project path. 93 | 94 | """ 95 | # Fix path name according to OS flavor 96 | separator, new_separator = ("/", "\\") if os.name != "posix" else ("/", "/") 97 | 98 | # Sort expected and current structures 99 | expected_structure = sorted( 100 | [file.replace(separator, new_separator) for file in expected_structure] 101 | ) 102 | current_structure = sorted( 103 | [ 104 | str(file.relative_to(project_path)).replace(separator, new_separator) 105 | for file in project_path.glob("**/*") if file.is_file() 106 | ] 107 | ) 108 | 109 | try: 110 | for current_file, expected_file in zip(current_structure, expected_structure): 111 | assert current_file == expected_file 112 | 113 | assert len(current_structure) == len(expected_structure) 114 | except AssertionError: 115 | msg = f"File {current_file} not equals to {expected_file}\n\n" 116 | msg += f"Current structure = {current_structure}\n" 117 | msg += f"Expected structure = {expected_structure}\n" 118 | raise AssertionError(msg) 119 | -------------------------------------------------------------------------------- /tests/test_cli.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. 2 | # SPDX-License-Identifier: MIT 3 | # 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | from click.testing import CliRunner 24 | import pytest 25 | 26 | from ansys.templates import AVAILABLE_TEMPLATES_AND_DESCRIPTION, __version__ 27 | from ansys.templates.cli import main 28 | 29 | 30 | def test_cli_main_group(): 31 | runner = CliRunner() 32 | result = runner.invoke(main, ["--help"]) 33 | assert result.exit_code == 0 34 | 35 | assert "Ansys tool for creating new Ansys projects." in result.output 36 | 37 | assert "list List all available templates names." in result.output 38 | assert "new Create a new project from desired template." in result.output 39 | assert "version Display current version" in result.output 40 | 41 | 42 | def test_cli_main_list_command(): 43 | runner = CliRunner() 44 | result = runner.invoke(main, ["list"]) 45 | assert result.exit_code == 0 46 | 47 | assert "Available templates in ansys-templates are:" in result.output 48 | 49 | for template, description in AVAILABLE_TEMPLATES_AND_DESCRIPTION.items(): 50 | assert f"{template.replace('_', '-')}: {description}" in result.output 51 | 52 | 53 | def test_cli_main_new_group(): 54 | runner = CliRunner() 55 | result = runner.invoke(main, ["new", "--help"]) 56 | assert result.exit_code == 0 57 | 58 | assert "Create a new project from desired template." in result.output 59 | 60 | for template, description in AVAILABLE_TEMPLATES_AND_DESCRIPTION.items(): 61 | expected_output = ( 62 | f" {template.replace('_', '-')}" + " " * (24 - len(template)) + f"{description[:40]}" 63 | ) 64 | assert expected_output in result.output 65 | 66 | 67 | def test_cli_main_version_command(): 68 | runner = CliRunner() 69 | result = runner.invoke(main, ["version"]) 70 | assert result.exit_code == 0 71 | 72 | assert f"ansys-templates {__version__}" in result.output 73 | 74 | 75 | @pytest.mark.parametrize("template", AVAILABLE_TEMPLATES_AND_DESCRIPTION.keys()) 76 | def test_cli_main_new(template): 77 | runner = CliRunner() 78 | with runner.isolated_filesystem() as td: 79 | result = runner.invoke(main, ["new", template.replace("_", "-")]) 80 | assert result.exit_code == 0 81 | -------------------------------------------------------------------------------- /tests/test_testing.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 - 2025 ANSYS, Inc. and/or its affiliates. 2 | # SPDX-License-Identifier: MIT 3 | # 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import os 24 | 25 | from ansys.templates.testing import assert_files_in_baked_project, assert_template_baking_process 26 | 27 | 28 | def test_assert_files_in_baked_project(tmp_path): 29 | files_list = ["file_A.txt", "file_B.txt", "file_C.txt"] 30 | for file in files_list: 31 | (tmp_path / file).touch() 32 | 33 | assert_files_in_baked_project(files_list, tmp_path) 34 | 35 | 36 | def test_assert_template_baking_process(tmp_path): 37 | # Create a tiny family template 38 | os.mkdir(tmp_path / "common") 39 | os.mkdir(tmp_path / "common/{{cookiecutter.__project_name_slug}}") 40 | os.mkdir(tmp_path / "template") 41 | os.mkdir(tmp_path / "template/{{cookiecutter.__project_name_slug}}") 42 | 43 | # Fill the common cookiecutter file 44 | with open(tmp_path / "common/cookiecutter.json", "w") as common_file: 45 | file_content = """ 46 | { 47 | "__project_name_slug": "" 48 | } 49 | """ 50 | common_file.write(file_content) 51 | 52 | # Fill the template cookiecutter file 53 | with open(tmp_path / "template/cookiecutter.json", "w") as template_file: 54 | file_content = """ 55 | { 56 | "project_name_slug": "hello_project", 57 | "__project_name_slug": "{{ cookiecutter.project_name_slug }}" 58 | } 59 | """ 60 | template_file.write(file_content) 61 | 62 | assert_template_baking_process( 63 | tmp_path / "template", tmp_path, dict(project_name_slug="hello_project") 64 | ) 65 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | description = Default environments to be executed when calling tox 3 | envlist = 4 | style 5 | {py39,py310,py311,py312}{,-keep-output}{,-python} 6 | doc 7 | isolated_build = true 8 | isolated_build_env = build 9 | 10 | [testenv] 11 | description = Generic environment configuration 12 | basepython = 13 | py39: python3.9 14 | py310: python3.10 15 | py311: python3.11 16 | py312: python3.12 17 | py: python3 18 | {style,doc,build}: python3 19 | passenv = * 20 | setenv = 21 | PYTHONUNBUFFERED = yes 22 | smoke: PYTEST_MARKERS = -k "not tests_templates" 23 | python: PYTEST_MARKERS = -k "tests_templates_python" 24 | template: PYTEST_MARKERS = -k "{env:TEMPLATE:}" 25 | keep-output: PYTEST_EXTRA_ARGS = --basetemp=output 26 | cov: PYTEST_EXTRA_ARGS = --cov=ansys.templates --cov-report=term --cov-report=xml:.cov/xml --cov-report=html:.cov/html 27 | skip_install = false 28 | extras = 29 | tests 30 | commands = 31 | pytest {env:PYTEST_MARKERS:} {env:PYTEST_EXTRA_ARGS:} {posargs: tests -vvv} 32 | 33 | [testenv:style] 34 | description = Checks if code style applies 35 | skip_install = true 36 | deps = 37 | pre-commit 38 | commands = 39 | pre-commit install 40 | pre-commit run --all-files --show-diff-on-failure 41 | 42 | [testenv:doc] 43 | description = Checks if project documentation properly builds 44 | skip_install = false 45 | extras = 46 | doc 47 | allowlist_externals=* 48 | commands = 49 | sphinx-build -d "{toxworkdir}/doc_doctree" doc/source "{toxinidir}/doc/_build/html" --color -vW -bhtml 50 | --------------------------------------------------------------------------------