Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEAT: add ansys-api-template #281

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 18 additions & 12 deletions .github/workflows/templates_python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@ on:
- main
workflow_dispatch:

env:
MAIN_PYTHON_VERSION: '3.8'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:

tests:
name: ${{ matrix.cfg.template }} / ${{ matrix.cfg.build-system }} / ${{ matrix.python-version }}
name: "${{ matrix.cfg.template }} / ${{ matrix.cfg.build-system }} / ${{ matrix.python-version }}"
runs-on: ubuntu-latest
strategy:
matrix:
Expand All @@ -29,7 +32,6 @@ jobs:
- python-version: "3.11"
toxenv: py311
toxextra: keep-output

cfg:
# All pybasic template tests
- {name: "doc-project", template: "doc-project", build-system: "flit", outdir: "doc_proje0/doc-project"}
Expand All @@ -47,6 +49,9 @@ jobs:
- {name: "pyansys-advanced-poetry", template: "pyansys-advanced", build-system: "poetry", outdir: "pyansys_a1/pyproduct-library"}
- {name: "pyansys-advanced-setuptools", template: "pyansys-advanced", build-system: "setuptools", outdir: "pyansys_a2/pyproduct-library"}

# All ansys API templates
- {name: "ansys-api", template: "ansys-api", build-system: "setuptools", outdir: "ansys_api2/ansys-api-product-library"}

# # All pyace template tests
- {name: "pyace-pkg", template: "pyace", build-system: "setuptools", outdir: "pyace_set0/project"}
- {name: "pyace-flask", template: "pyace-flask", build-system: "setuptools", outdir: "pyace_fla2/project"}
Expand All @@ -57,41 +62,42 @@ jobs:
- {name: "solution", template: "solution", build-system: "poetry", outdir: "solution_1/solution"}

fail-fast: false

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
- name: "Checkout project"
uses: actions/checkout@v3

- name: "Set up Python ${{ matrix.python-version }}"
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
- name: "Install dependencies"
run: |
python -m pip install --upgrade pip tox

- name: Bake ${{ matrix.cfg.template }}
- name: "Bake ${{ matrix.cfg.template }}"
run: |
export TEMPLATE=${{ matrix.cfg.template }}
tox -e ${{ matrix.toxenv }}-${{ matrix.toxextra }}-template
tox -r -e ${{ matrix.toxenv }}-${{ matrix.toxextra }}-template

- name: Move baked project to repo again
if: matrix.python-version == '3.8' && github.event_name == 'push'
- name: "Move baked project to repo again"
if: matrix.python-version == env.MAIN_PYTHON_VERSION && github.event_name == 'push'
run: |
mv "output/test_template_python_${{ matrix.cfg.outdir }}" baked_template
# GitHub Apps are not allowed to deal with .github workflows
if [ -d "baked_template/.github" ]; then mv baked_template/.github baked_template/.github_demo; fi
ls -a baked_template

- name: Create demo branch
if: matrix.python-version == '3.8' && github.event_name == 'push'
if: matrix.python-version == env.MAIN_PYTHON_VERSION && github.event_name == 'push'
uses: peterjgrainger/[email protected]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
branch: "demo/${{ matrix.cfg.name }}"

- name: Publish demo branch
if: matrix.python-version == '3.8' && github.event_name == 'push'
if: matrix.python-version == env.MAIN_PYTHON_VERSION && github.event_name == 'push'
uses: s0/git-publish-subdir-action@develop
env:
REPO: self
Expand Down
1 change: 1 addition & 0 deletions src/ansys/templates/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"pybasic": "Create a basic Python Package.",
"pyansys": "Create a PyAnsys Python Package project.",
"pyansys-advanced": "Create an advanced PyAnsys Python Package project.",
"ansys-api": "Create a new gRPC API definition.",
"pyansys-openapi_client": "Create an OpenAPI Client Package project.",
"pyace": "Create a Python project for any method developers.",
"pyace-flask": "Create a Flask project initialized for any developer.",
Expand Down
6 changes: 6 additions & 0 deletions src/ansys/templates/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ def pyansys_advanced():
create_project("pyansys-advanced")


@new.command()
def ansys_api():
"""Create a new gRPC API definition."""
create_project("ansys-api")


@new.command()
def pyansys_openapi_client():
"""Create an OpenAPI Client Package project."""
Expand Down
4 changes: 4 additions & 0 deletions src/ansys/templates/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
PYTHON_TEMPLATES_PYANSYS_ADVANCED_PATH = PYTHON_TEMPLATES_PATH / "pyansys_advanced"
"""Path to the advanced PyAnsys Python Package template."""

PYTHON_TEMPLATES_ANSYS_API_PATH = PYTHON_TEMPLATES_PATH / "ansys_api"
"""Path to the Ansys API Python Package template."""

PYTHON_TEMPLATES_PYANSYS_OPENAPI_CLIENT_PATH = PYTHON_TEMPLATES_PATH / "pyansys_openapi_client"
"""Path to the PyAnsys OpenAPI Client Package template."""

Expand Down Expand Up @@ -79,6 +82,7 @@
"pybasic": PYTHON_TEMPLATES_PYBASIC_PATH,
"pyansys": PYTHON_TEMPLATES_PYANSYS_PATH,
"pyansys-advanced": PYTHON_TEMPLATES_PYANSYS_ADVANCED_PATH,
"ansys-api": PYTHON_TEMPLATES_ANSYS_API_PATH,
"pyansys-openapi-client": PYTHON_TEMPLATES_PYANSYS_OPENAPI_CLIENT_PATH,
"pyace": PYTHON_TEMPLATES_PYACE_PATH,
"pyace-grpc": PYTHON_TEMPLATES_PYACE_GRPC_PATH,
Expand Down
30 changes: 30 additions & 0 deletions src/ansys/templates/python/ansys_api/cookiecutter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"__template_name": "ansys-api",
"product_name": "",
"__product_name_slug": "{{ cookiecutter.product_name | slugify(separator=('_')) }}",
"library_name": "",
"__library_name_slug": "{{ cookiecutter.library_name | slugify(separator=('_')) }}",
"__project_name_slug": "ansys-api-{{ cookiecutter.__product_name_slug }}{% if cookiecutter.__library_name_slug %}-{{ cookiecutter.__library_name_slug }}{% endif %}",
"__pkg_name": "{{ cookiecutter.__project_name_slug }}",
"api_version": "0",
"__api_version": "{{ cookiecutter.api_version }}",
"__pkg_namespace": "ansys.api.{{ cookiecutter.__product_name_slug }}.{{ cookiecutter.__library_name_slug }}",
"__pkg_namespace_with_version": "{{ cookiecutter.__pkg_namespace}}-v{{ cookiecutter.__api_version }}",
"version": "0.1.dev0",
"__version": "{{ cookiecutter.version }}",
"short_description": "A collection of gRPC API definitions for Ansys {{ cookiecutter.product_name }} {{ cookiecutter.library_name }}",
"__short_description": "{{ cookiecutter.short_description | capitalize }}",
"protos_dir": "",
"proto_dependencies": {
"modules": []
},
"__requires_python": "",
"__repository_url": "",
"__build_system": "setuptools",
"__logo": "",
"__logo_color": "",
"__max_linelength": "",
"__coverage_source": "",
"__is_pyansys": "false",
"_extensions": ["cookiecutter.extensions.SlugifyExtension"]
}
27 changes: 27 additions & 0 deletions src/ansys/templates/python/ansys_api/hooks/post_gen_project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Hook to copy the .proto files into the project, and create __init__.py and py.typed files."""

from ansys.templates.utils import keep_files

src_path = "src/ansys/api/{{ cookiecutter.__product_name_slug }}"

if "{{ cookiecutter.__library_name_slug }}" != "":
src_path += "/{{ cookiecutter.__library_name_slug }}"

DESIRED_STRUCTURE = [
"README.md",
"pyproject.toml",
"setup.py",
f"{src_path}/__init__.py",
f"{src_path}/VERSION",
f"{src_path}/py.typed",
".github/workflows/ci.yml",
]
"""A list holding all desired files to be included in the project."""

def main():
"""Entry point of the script."""
# Apply the desired structure to the project
keep_files(DESIRED_STRUCTURE)

if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: CI

on:
pull_request:
push:
tags:
- "*"
branches:
- main

env:
MAIN_PYTHON_VERSION: '3.10'
LIBRARY_NAME: '{{ cookiecutter.__pkg_namespace | replace(".", "-") }}'
LIBRARY_NAMESPACE: '{{ cookiecutter.__pkg_namespace }}'

concurrency:
group: {{ '${{ github.workflow }}-${{ github.ref }}' }}
cancel-in-progress: true

jobs:

tests:
name: "Build package"
runs-on: ubuntu-latest
steps:

- name: "Checkout repository"
uses: actions/checkout@v3

- name: "Setup Python"
uses: actions/setup-python@v4
with:
python-version: {{ '${{ env.MAIN_PYTHON_VERSION }}' }}

- name: "Install the library"
run: |
python -m pip install .

- name: "Test import"
run: |
{{ 'python -c "from ${{ env.LIBRARY_NAMESPACE }} import __version__; print(__version__)"' }}

build-library:
name: "Build library"
needs: tests
runs-on: ubuntu-latest
steps:
- uses: ansys/actions/build-library@v4
with:
library-name: {{ '${{ env.LIBRARY_NAME }}' }}

release:
name: "Release library"
if: github.event_name == 'push' && contains(github.ref, 'refs/tags')
needs: build-package
runs-on: ubuntu-latest
steps:

- name: "Release to the private PyPI"
uses: ansys/actions/release-pypi-private@v4
with:
library-name: {{ '${{ env.LIBRARY_NAME }}' }}
twine-username: "__token__"
twine-token: {{ '${{ secrets.PYANSYS_PYPI_PRIVATE_PAT }}' }}

- name: "Release to GitHub"
uses: softprops/action-gh-release@v1
with:
generate_release_notes: true
files: |
{{ '${{ env.LIBRARY_NAME }}-artifacts/*.whl }}' }}
{{ '${{ env.LIBRARY_NAME }}-artifacts/*.tar.gz' }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
### {{ cookiecutter.__project_name_slug }} gRPC Interface Package

This Python package contains the auto-generated gRPC Python interface files for
{{ cookiecutter.product_name }}.


#### Installation

Provided that these wheels have been published to public PyPI, they can be
installed with:

```
pip install {{ cookiecutter.__project_name_slug | lower }}
```

Otherwise, see the


#### Build

To build the gRPC packages, run:

```
pip install build
python -m build
```

This will create both the source distribution containing just the protofiles
along with the wheel containing the protofiles and build Python interface
files.

Note that the interface files are identical regardless of the version of Python
used to generate them, but the last pre-built wheel for ``grpcio~=1.17`` was
Python 3.7, so to improve your build time, use Python 3.7 when building the
wheel.


#### Manual Deployment

After building the packages, manually deploy them with:

```
pip install twine
twine upload dist/*
```

Note that this is automatically done through CI/CD.


#### Automatic Deployment

This repository contains GitHub CI/CD that enables the automatic building of
source and wheel packages for these gRPC Python interface files. By default,
these are built on PRs, the main branch, and on tags when pushing. Artifacts
are uploaded for each PR.

To publicly release wheels to PyPI, ensure your branch is up-to-date and then
push tags. For example, for the version ``v0.5.0``.

```bash
git tag v0.5.0
git push --tags
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools >= 42.0.0", "wheel", "ansys_tools_protoc_helper"{% for mod in cookiecutter.proto_dependencies['modules'] %}, "{{ mod }}"{% endfor %}]
build-backend = "setuptools.build_meta:__legacy__"
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""Installation file for the {{ cookiecutter.__project_name_slug }} package"""

import os
from datetime import datetime

import setuptools

from ansys.tools.protoc_helper import CMDCLASS_OVERRIDE

# Get the long description from the README file
HERE = os.path.abspath(os.path.dirname(__file__))
with open(os.path.join(HERE, "README.md"), encoding="utf-8") as f:
long_description = f.read()

product = "{{ cookiecutter.__product_name_slug }}"
library = "{{ cookiecutter.__library_name_slug }}"
package_info = ["ansys", "api", product, library, "v{{ cookiecutter.__api_version }}"]
with open(os.path.join(HERE, "src", "ansys", "api", product, library, "VERSION"), encoding="utf-8") as f:
version = f.read().strip()

package_name = "{{ cookiecutter.__project_name_slug }}"
dot_package_name = '.'.join(filter(None, package_info))

description = f"Autogenerated python gRPC interface package for {package_name}, built on {datetime.now().strftime('%H:%M:%S on %d %B %Y')}"

if __name__ == "__main__":
setuptools.setup(
name=package_name,
version=version,
author="ANSYS, Inc.",
author_email='[email protected]',
description=description,
short_description="{{ cookiecutter.__short_description }}",
long_description=long_description,
long_description_content_type='text/markdown',
url=f"https://github.com/ansys/{package_name}",
license="MIT",
python_requires=">=3.7",
install_requires=["grpcio~=1.17", "protobuf~=3.19"{% for mod in cookiecutter.proto_dependencies['modules'] %}, "{{ mod }}"{% endfor %}],
package_dir = {"": "src"},
packages=setuptools.find_namespace_packages("src", include=("ansys.*",)),
package_data={
"": ["*.proto", "*.pyi", "py.typed", "VERSION"],
},
entry_points={
"ansys.tools.protoc_helper.proto_provider": [
f"{dot_package_name}={dot_package_name}"
],
},
cmdclass=CMDCLASS_OVERRIDE
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Autogenerated Python gRPC interface package for {{ cookiecutter.__project_name_slug }}."""

import pathlib

__all__ = ["__version__"]

with open(pathlib.Path(__file__).parent / "VERSION", encoding="utf-8") as f:
__version__ = f.read().strip()
Loading