[1]:
"""Sphinx documentation configuration file."""
[1]:
'Sphinx documentation configuration file.'
[2]:
from datetime import datetime
import os
import pathlib
import shutil
[3]:
from ansys_sphinx_theme import ansys_favicon, get_version_match
import sphinx
from sphinx.builders.latex import LaTeXBuilder
from sphinx.util import logging
from sphinx.util.display import status_iterator
[4]:
from ansys.speos.core import __version__
[5]:
LaTeXBuilder.supported_image_types = ["image/png", "image/pdf", "image/svg+xml"]
os.environ["DOCUMENTATION_BUILDING"] = "true"
os.environ["PYANSYS_VISUALIZER_HTML_BACKEND"] = "true"
logger = logging.getLogger(__name__)
[6]:
# Project information
project = "ansys-speos-core"
copyright = f"(c) {datetime.now().year} ANSYS, Inc. All rights reserved"
author = "Ansys Inc."
release = version = __version__
cname = os.getenv("DOCUMENTATION_CNAME", default="speos.docs.pyansys.com")
[7]:
# use the default pyansys logo
html_theme = "ansys_sphinx_theme"
html_favicon = ansys_favicon
[8]:
# specify the location of your github repo
html_theme_options = {
"logo": "pyansys",
"github_url": "https://github.com/ansys/pyspeos",
"show_prev_next": False,
"switcher": {
"json_url": f"https://{cname}/versions.json",
"version_match": get_version_match(__version__),
},
"check_switcher": False,
"ansys_sphinx_theme_autoapi": {
"project": project,
},
}
BUILD_CHEATSHEET = os.environ.get("BUILD_CHEATSHEET", "false").lower() == "true"
if BUILD_CHEATSHEET:
html_theme_options["cheatsheet"] = {
"file": "cheat_sheet/cheat_sheet_script.qmd",
"title": "PySpeos cheat sheet",
"version": f"v{version}",
"pages": ["index"],
}
[9]:
# Sphinx extensions
extensions = [
"numpydoc",
"sphinx.ext.intersphinx",
"sphinx_copybutton",
"sphinx.ext.autodoc",
"sphinx_design",
"sphinx_jinja",
"ansys_sphinx_theme.extension.autoapi",
"nbsphinx",
"myst_parser",
"sphinxcontrib.mermaid",
]
[10]:
# Intersphinx mapping
intersphinx_mapping = {
"python": ("https://docs.python.org/3/", None),
"grpc": ("https://grpc.github.io/grpc/python/", None),
"pypim": ("https://pypim.docs.pyansys.com/version/stable", None),
# kept here as an example
# "scipy": ("https://docs.scipy.org/doc/scipy/reference", None),
# "numpy": ("https://numpy.org/devdocs", None),
# "matplotlib": ("https://matplotlib.org/stable", None),
# "pandas": ("https://pandas.pydata.org/pandas-docs/stable", None),
# "pyvista": ("https://docs.pyvista.org/", None),
}
[11]:
numpydoc_show_class_members = False
numpydoc_xref_param_type = True
numpydoc_validate = True
numpydoc_validation_checks = {
"GL06", # Found unknown section
"GL07", # Sections are in the wrong order.
# "GL08", # The object does not have a docstring
"GL09", # Deprecation warning should precede extended summary
"GL10", # reST directives {directives} must be followed by two colons
"SS01", # No summary found
"SS02", # Summary does not start with a capital letter
# "SS03", # Summary does not end with a period
"SS04", # Summary contains heading whitespaces
# "SS05", # Summary must start with infinitive verb, not third person
"RT02", # The first line of the Returns section should contain only the
# type, unless multiple values are being returned"
}
[12]:
# static path
html_static_path = ["_static"]
html_css_files = ["custom.css"]
[13]:
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
[14]:
# The suffix(es) of source filenames.
source_suffix = ".rst"
[15]:
# The master toctree document.
master_doc = "index"
suppress_warnings = ["autoapi"]
autodoc_typehints = "description"
[16]:
# -- Declare the Jinja context -----------------------------------------------
BUILD_EXAMPLES = True if os.environ.get("BUILD_EXAMPLES", "true") == "true" else False
if BUILD_EXAMPLES:
extensions.extend(["myst_parser", "nbsphinx"])
nbsphinx_execute = "always"
nbsphinx_custom_formats = {
".mystnb": ["jupytext.reads", {"fmt": "mystnb"}],
".py": ["jupytext.reads", {"fmt": ""}],
}
nbsphinx_thumbnails = {
"examples/core/bsdf": "_static/thumbnails/bsdf.png",
"examples/core/opt-prop": "_static/thumbnails/property_520x520.png",
"examples/core/source": "_static/thumbnails/source_520x520.png",
"examples/core/sensor": "_static/thumbnails/sensor_520x520.png",
"examples/core/part": "_static/thumbnails/part_520x520.png",
"examples/core/simulation": "_static/thumbnails/simulation_520x520.png",
"examples/core/project": "_static/thumbnails/how_to_create_a_project.PNG",
"examples/core/lpf-preview": "_static/thumbnails/script_lpf_preview.PNG",
"examples/core/prism-example": "_static/thumbnails/prism_example_using_script_layer.PNG",
"examples/kernel/object-link": "_static/thumbnails/pySpeos_520x520.png",
"examples/kernel/scene-job": "_static/thumbnails/pySpeos_520x520.png",
"examples/kernel/modify-scene": "_static/thumbnails/pySpeos_520x520.png",
"examples/workflow/open-result": "_static/thumbnails/workflow_open_result.png",
"examples/workflow/combine-speos": "_static/thumbnails/workflow_moving_car.PNG",
}
nbsphinx_prompt_width = ""
nbsphinx_prolog = """
.. grid:: 5
.. grid-item::
.. grid-item::
:child-align: center
.. button-link:: {cname_pref}/{python_file_loc}
:color: primary
:shadow:
Download as Python script :fab:`python`
.. grid-item::
:child-align: center
.. button-link:: {cname_pref}/{ipynb_file_loc}
:color: primary
:shadow:
Download as Jupyter notebook :fas:`book`
.. grid-item::
:child-align: center
.. button-link:: {cname_pref}/{assets_loc}
:color: primary
:shadow:
Download example's assets :fa:`file`
.. grid-item::
----
""".format(
cname_pref=f"https://{cname}/version/{get_version_match(version)}",
python_file_loc="{{ env.docname }}.py",
ipynb_file_loc="{{ env.docname }}.ipynb",
assets_loc="_static/assets/download/assets.zip",
)
[17]:
jinja_contexts = {
"linux_containers": {},
"main_toctree": {
"build_examples": BUILD_EXAMPLES,
},
}
[18]:
def copy_examples_to_output_dir(app: sphinx.application.Sphinx, exception: Exception):
"""
Copy the examples directory to the output directory of the documentation.
Parameters
----------
app : sphinx.application.Sphinx
Sphinx application instance containing the all the doc build configuration.
exception : Exception
Exception encountered during the building of the documentation.
"""
OUTPUT_EXAMPLES = pathlib.Path(app.outdir) / "examples"
OUTPUT_IMAGES = OUTPUT_EXAMPLES / "img"
OUTPUT_CORE = OUTPUT_EXAMPLES / "core"
OUTPUT_KERNEL = OUTPUT_EXAMPLES / "kernel"
OUTPUT_WORKFLOW = OUTPUT_EXAMPLES / "workflow"
for directory in [
OUTPUT_EXAMPLES,
OUTPUT_IMAGES,
OUTPUT_CORE,
OUTPUT_KERNEL,
OUTPUT_WORKFLOW,
]:
if not directory.exists():
directory.mkdir(parents=True, exist_ok=True)
SOURCE_EXAMPLES = pathlib.Path(app.srcdir) / "examples"
EXAMPLES_DIRECTORY = SOURCE_EXAMPLES.parent.parent.parent / "examples"
# Copyt the examples
examples = list(EXAMPLES_DIRECTORY.glob("**/*.py"))
for file in status_iterator(
examples,
"Copying example to doc/_build/examples/",
"green",
len(examples),
verbosity=1,
stringify_func=(lambda file: file.name),
):
destination_file = OUTPUT_EXAMPLES / file.parent.name / file.name
destination_file.write_text(file.read_text(encoding="utf-8"), encoding="utf-8")
[19]:
def copy_examples_files_to_source_dir(app: sphinx.application.Sphinx):
"""
Copy the examples directory to the source directory of the documentation.
Parameters
----------
app : sphinx.application.Sphinx
Sphinx application instance containing the all the doc build configuration.
"""
SOURCE_EXAMPLES = pathlib.Path(app.srcdir) / "examples"
SOURCE_IMAGES = SOURCE_EXAMPLES / "img"
CORE_EXAMPLES = SOURCE_EXAMPLES / "core"
KERNEL_EXAMPLES = SOURCE_EXAMPLES / "kernel"
WORKFLOW_EXAMPLES = SOURCE_EXAMPLES / "workflow"
for directory in [
SOURCE_EXAMPLES,
SOURCE_IMAGES,
CORE_EXAMPLES,
KERNEL_EXAMPLES,
WORKFLOW_EXAMPLES,
]:
if not directory.exists():
directory.mkdir(parents=True, exist_ok=True)
EXAMPLES_DIRECTORY = SOURCE_EXAMPLES.parent.parent.parent / "examples"
# Copy the the examples
examples = list(EXAMPLES_DIRECTORY.glob("**/*.py"))
for file in status_iterator(
examples,
"Copying example to doc/source/examples/",
"green",
len(examples),
verbosity=1,
stringify_func=(lambda file: file.name),
):
destination_file = SOURCE_EXAMPLES / file.parent.name / file.name
destination_file.write_text(file.read_text(encoding="utf-8"), encoding="utf-8")
[20]:
def copy_assets_to_output_dir(app: sphinx.application.Sphinx, exception: Exception):
"""Copy the assets directory to the output directory of the documentation.
Parameters
----------
app : sphinx.application.Sphinx
Sphinx application instance containing the all the doc build configuration.
exception : Exception
Exception encountered during the building of the documentation.
"""
if app.builder.name == "html":
SOURCE_ASSETS = pathlib.Path(app.outdir) / "_static" / "assets" / "download"
ASSETS_DIRECTORY = pathlib.Path(app.outdir).parent.parent.parent / "tests" / "assets"
logger.info("Extracting assets to output directory...")
zip_path = pathlib.Path(shutil.make_archive("assets", "zip", ASSETS_DIRECTORY))
zip_path = shutil.move(zip_path, SOURCE_ASSETS / zip_path.name)
logger.info(f"Extracted assets to {zip_path}.")
else:
logger.info(f"Skip assets extraction with build {app.builder.name}.")
[21]:
def remove_examples_from_source_dir(app: sphinx.application.Sphinx, exception: Exception):
"""
Remove the example files from the documentation source directory.
Parameters
----------
app : sphinx.application.Sphinx
Sphinx application instance containing the all the doc build configuration.
exception : Exception
Exception encountered during the building of the documentation.
"""
EXAMPLES_DIRECTORY = pathlib.Path(app.srcdir) / "examples"
logger.info(f"\nRemoving {EXAMPLES_DIRECTORY} directory...")
shutil.rmtree(EXAMPLES_DIRECTORY)
[22]:
def setup(app: sphinx.application.Sphinx):
"""
Run different hook functions during the documentation build.
Parameters
----------
app : sphinx.application.Sphinx
Sphinx application instance containing the all the doc build configuration.
"""
# HACK: rST files are copied to the doc/source directory before the build.
# Sphinx needs all source files to be in the source directory to build.
# However, the examples are desired to be kept in the root directory. Once the
# build has completed, no matter its success, the examples are removed from
# the source directory.
if BUILD_EXAMPLES:
app.connect("builder-inited", copy_examples_files_to_source_dir)
app.connect("build-finished", remove_examples_from_source_dir)
app.connect("build-finished", copy_assets_to_output_dir)
app.connect("build-finished", copy_examples_to_output_dir)