From 7f134e330fb8683dfefe4dfb50c30489a25cb3bf Mon Sep 17 00:00:00 2001 From: Dominik Gresch Date: Mon, 5 Feb 2024 11:56:14 +0100 Subject: [PATCH] [WIP] Add doctest --- .github/workflows/ci_cd.yml | 78 +++++++++++++++++++++++++++++++++++++ doc/source/conf.py | 1 + doc/source/intro.rst | 55 ++++++++++++++++++-------- 3 files changed, 118 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index e7d1ee53f6..7ae72822c1 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -201,6 +201,84 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} if: matrix.python-version == '3.9' && github.ref == 'refs/heads/main' + doctest: + name: Test documentation snippets + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: ${{ env.MAIN_PYTHON_VERSION }} + + - name: Pip cache + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: pip-${{ runner.os }}-${{ hashFiles('poetry.lock') }}-doctest + restore-keys: | + pip-${{ runner.os }} + + - name: Install library, with test,dev groups + run: | + git config --global url."https://${{ secrets.PYANSYS_CI_BOT_TOKEN }}@github.com/ansys-internal/ansys-tools-filetransfer".insteadOf "https://github.com/ansys-internal/ansys-tools-filetransfer" + git config --global url."https://${{ secrets.PYANSYS_CI_BOT_TOKEN }}@github.com/ansys-internal/ansys-tools-local-product-launcher".insteadOf "https://github.com/ansys-internal/ansys-tools-local-product-launcher" + pip install -U pip + pip install 'poetry!=1.7.0' + poetry config http-basic.pyansys_private_pypi TOKEN ${{ secrets.PYANSYS_PYPI_PRIVATE_PAT }} + poetry install --with test,dev + + - name: Build API package from custom branch + if: "${{ github.event.inputs.api_branch != '' }}" + run: | + python3.10 -m venv .api_builder_venv + . .api_builder_venv/bin/activate + python -m pip install --upgrade pip wheel + mkdir .api_package + python -m pip wheel --no-deps --wheel-dir .api_package git+https://${{ secrets.PYANSYS_CI_BOT_TOKEN }}@github.com/ansys-internal/ansys-api-acp.git@${{ github.event.inputs.api_branch }} + + - name: Install custom API branch package + if: "${{ github.event.inputs.api_branch != '' }}" + run: | + poetry run pip install --force-reinstall .api_package/*.whl + + - name: Login in Github Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Install OS packages + run: | + sudo apt update + sudo apt-get install pandoc xvfb + + - name: Configure Local Product Launcher for ACP + working-directory: tests/unittests + run: > + poetry run + ansys-launcher configure ACP docker_compose + --image_name_pyacp=ghcr.io/ansys-internal/pyacp${{ github.event.inputs.docker_image_suffix || ':latest' }} + --image_name_filetransfer=ghcr.io/ansys-internal/tools-filetransfer:latest + --license_server=1055@$LICENSE_SERVER + --keep_volume=False + --overwrite_default + env: + LICENSE_SERVER: ${{ secrets.LICENSE_SERVER }} + + - name: Run doctest + run: | + docker pull $IMAGE_NAME + docker pull ghcr.io/ansys-internal/tools-filetransfer:latest + xvfb-run poetry run make -C doc doctest + env: + LICENSE_SERVER: ${{ secrets.LICENSE_SERVER }} + IMAGE_NAME: "ghcr.io/ansys-internal/pyacp${{ github.event.inputs.docker_image_suffix || ':latest' }}" + docs: name: Build Documentation runs-on: ubuntu-latest diff --git a/doc/source/conf.py b/doc/source/conf.py index 751c30d820..205f1e9223 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -76,6 +76,7 @@ # Sphinx extensions extensions = [ + "sphinx.ext.doctest", "sphinx.ext.autodoc", "sphinx.ext.autosummary", "sphinx.ext.intersphinx", diff --git a/doc/source/intro.rst b/doc/source/intro.rst index b6f3dcc7a6..526e5adf82 100644 --- a/doc/source/intro.rst +++ b/doc/source/intro.rst @@ -21,14 +21,14 @@ Start ACP Start a Python interpreter and import the PyACP package: -.. code-block:: python +.. testcode:: - import ansys_acp.core as pyacp + import ansys.acp.core as pyacp Next, start an ACP instance: -.. code-block:: python +.. testcode:: acp = pyacp.launch_acp() @@ -37,16 +37,36 @@ Load a model To load a model in ACP, use the :meth:`import_model <.ACP.import_model>` method: -.. code-block:: python +.. testcode:: + :hide: - model = acp.import_model(path="path/to/model.acph5") + import os + import shutil + import tempfile + + with tempfile.TemporaryDirectory() as tempdir: + tmp_file = os.path.join(tempdir, "model.acph5") + shutil.copy("../tests/data/minimal_complete_model.acph5", tmp_file) + acp.upload_file(tmp_file) + +.. testcode:: + + model = acp.import_model(path="model.acph5") This can be either an existing ACP model (``.acph5`` format) or an FE model. When an FE model is loaded, the format needs to be specified: -.. code-block:: python +.. testcode:: + :hide: + + with tempfile.TemporaryDirectory() as tempdir: + tmp_file = os.path.join(tempdir, "model.cdb") + shutil.copy("../tests/data/minimal_model_2.cdb", tmp_file) + acp.upload_file(tmp_file) + +.. testcode:: - model = acp.load_model(path="path/to/model.cdb", format="ansys:cdb") + model = acp.import_model(path="model.cdb", format="ansys:cdb") See :class:`.FeFormat` for a list of supported FE formats. @@ -56,7 +76,7 @@ Start modelling Start defining new objects in the model. For example, to create a new modeling group and modeling ply: -.. code-block:: python +.. testcode:: modeling_group = model.create_modeling_group(name="Modeling Group 1") modeling_ply = modeling_group.create_modeling_ply(name="Ply 1", ply_angle=10.0) @@ -66,7 +86,7 @@ For example, refer to the documentation of :meth:`create_modeling_ply <.Modeling Alternatively, you can always set the properties of an object after it has been created: -.. code-block:: python +.. testcode:: fabric = model.create_fabric(name="Fabric 1") modeling_ply.ply_material = fabric @@ -81,9 +101,9 @@ Save the model To save the model, use the :meth:`save <.Model.save>` method: -.. code-block:: python +.. testcode:: - model.save("path/to/saved/model.acph5") + model.save("saved_model.acph5") Update and plot the model @@ -91,21 +111,24 @@ Update and plot the model To update the model, use the :meth:`update <.Model.update>` method: -.. code-block:: python +.. doctest:: - model.update() # Note: our model is still incomplete, so this will raise an error + >>> model.update() # Note: our model is still incomplete, so this will raise an error + Traceback (most recent call last): + ... + RuntimeError: Unknown error: No orthotropic material assigned to fabric Fabric 1! Many PyACP objects provide data which can be plotted. For example, to show the mesh: -.. code-block:: python +.. testcode:: - model.mesh.to_pyvista.plot() + model.mesh.to_pyvista().plot() Or to show the thickness of a modeling ply: -.. code-block:: python +.. testcode:: modeling_ply.elemental_data.thickness.get_pyvista_mesh(mesh=model.mesh).plot()