Skip to content

Commit

Permalink
Test code examples in docs (#387)
Browse files Browse the repository at this point in the history
Add the `sphinx.ext.doctest` plugin to the documentation, and run the
`doctest` check in a separate CI job to ensure the code examples in
the docs are working.

Closes #384
  • Loading branch information
greschd authored Feb 6, 2024
1 parent 1eb256a commit e0c7db6
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 16 deletions.
80 changes: 80 additions & 0 deletions .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,86 @@ 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' }}"
PYACP_DOC_SKIP_GALLERY: "true"
PYACP_DOC_SKIP_API: "true"

docs:
name: Build Documentation
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@

# Sphinx extensions
extensions = [
"sphinx.ext.doctest",
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
"sphinx.ext.intersphinx",
Expand Down
55 changes: 39 additions & 16 deletions doc/source/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand All @@ -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.

Expand All @@ -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)
Expand All @@ -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
Expand All @@ -81,31 +101,34 @@ 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
~~~~~~~~~~~~~~~~~~~~~~~~~

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()

Expand Down

0 comments on commit e0c7db6

Please sign in to comment.