Project structure#

Most of the projects in the PyAnsys ecosystem ship in the form of a Python library with other additional files. All these files form what it is called a project. A project can be uploaded to a repository to better track the changes applied to it.

Naming convention#

Large organizations providing Python packages follow a consistent naming convention. Ansys follows two naming conventions, depending on the nature of the project.

PyAnsys library#

  • The project name is in the format Py<project>. For example, PyAEDT is the project name for AEDT (Ansys Electronics Desktop) and PyMAPDL is the project name for MAPDL (an abbreviation for Mechanical APDL).

  • The repository name as hosted on GitHub should be all lowercase to follow GitHub community standards. For example, pyaedt and pymapdl.

  • The Python library name is in the format ansys-<product/service>-<feature>. For example, ansys-mapdl-core is the name for the core MAPDL library.

Namespace convention for PyAnsys projects.

Fig. 4 Namespace convention for PyAnsys projects.#

The previous structure leads to the following namespace when executing the import statement:

from ansys.product import library

Using long Python library names provides two primary advantages:

  • Namespace packages can be used to designate official Ansys packages.

  • Consistent branding and style can be applied to PyAnsys libraries.

gRPC interface package#

Lower-level gRPC interface packages like ansys-api-mapdl should always be named ansys-api-<product/service> and may contain an additional level: ansys-api-<product/service>-<secondlevel>.

Namespace convention for gRPC interface packages.

Fig. 5 Namespace convention for gRPC interface packages.#

This structure leads to the following namespace within Protobuf (PROTO) files:

package ansys.api.<product/service>.v0;

Python libraries#

A Python library is the formal way of distributing Python source code. It allows for reuse and for specifying Python code dependencies. Guidelines in this section are compliant with Python Packaging Authority (PyPA) and PyAnsys recommendations.

Note

The best way to keep up to date with Python packaging is to check the Python Packaging User Guide, maintained by the PyPA. PyAnsys guidelines are built on top of the PyPA guidelines.

Scripts, modules, subpackages, and packages#

To understand the structure of a Python Library, it is important to know the difference between Python scripts, modules, subpackages, and packages.

  • Script: Any Python file with logic source code

  • Module: Any Python script hosted next to an __init__.py file

  • Subpackage: Any directory containing various Python modules

  • Package: Any directory containing Python modules and subpackages

Differences between a Python package and library#

Although the terms package and library are often used interchangeably, there is a key difference between them. As shown in the following image, a Python package is a collection of Python modules and subpackages, while a Python library is a collection of Python packages.

A Python library is a collection of packages.

Fig. 6 A Python library is a collection of packages.#

Required files#

The structure of any PyAnsys library contains these directories and files:

Minimum required PyAnsys project structure.

Fig. 7 Minimum required PyAnsys project structure.#

Descriptions follow for some of the directories in this structure:

  • doc: Contains files related to documentation, guidelines, and examples

  • src: Contains all Python modules and scripts that form the project

  • tests: Contains all unit tests for checking the integrity of the project

  • setup.py or pyproject.toml: Configures the project.

The doc directory#

Prior to distributing software, it is important to document it. Documenting software consists of explaining how to install and use all functions, classes, and methods that it ships with. The documentation should also include use case scenarios.

A PyAnsys project typically has these documentation sections:

  • Getting started: Defines requirements and provides installation information

  • User guide: Explains how to use the software

  • API reference: Describes the source code

  • Examples: Provides use case scenarios that demonstrate the capabilities of the software

  • Contribute: Links to the PyAnsys developer’s guide for overall guidance and supplies project-specific contribution information

Projects in the PyAnsys ecosystem take advantage of Sphinx, a tool for building documentation for Python-based projects. Sphinx requires a doc directory with a specific structure:

Generic structure for the ``doc`` directory.

Fig. 8 Generic structure for the doc directory.#

  • _build: Contains the rendered documentation in various formats, such as HTML and PDF.

  • source: Contains the RST files with the manually authored content. Folder and file names in this directory should use hyphens as space delimiters for search optimization of the generated HTML documentation.

  • make.bat and Makefile: Automates documentation cleaning and building commands. You use make.bat when running on Windows and Makefile when running on macOS or Linux. For information on the required configuration for these files, see Automation files.

The source directory must contain at least these files:

  • conf.py: Python script that declares the Sphinx configuration. The minimum required configuration is explained in The conf.py file.

  • index.rst: Main index (landing) page for the overall documentation. Some projects reuse README.rst files in the main index.rst file. For more information, see README.rst files. In newer projects, however, the index.rst file uses a grid of cards to present the organization of the documentation in a visual manner.

You generally add any images or documents that you would like to include in a _static directory.

The src directory#

All the Python source code must be located in the src directory. This is where the build system looks when generating the wheel and source distributions.

Warning

The names of directories and files in the src directory cannot contain spaces or hyphens. Replace these characters with an underscore (_).

The structure of the src directory determines the namespace of the PyAnsys library. A namespace allow you to easily split subpackages from a package into single, independent distributions.

There are different approaches available for creating a namespace. Ansys namespaces use the native namespace packages from PEP 420.

Therefore, the source directory of any PyAnsys library must look like this:

Generic structure for the ``src`` directory.

Fig. 9 Generic structure for the src directory.#

The tests directory#

To guarantee the integrity of a PyAnsys project, a good test suite is required. PyAnsys projects use the pytest framework.

A good practice is to emulate the structure of the src/ansys/product/library directory, although this is not always necessary.

Minimum required PyAnsys project structure.

Fig. 10 Minimum required PyAnsys project structure.#

Notice the use of tests_* when creating child directories within the tests directory. For unit testing files, names use the test_*.py prefix. This is the preferred way of naming directories and files in the tests directory.

The AUTHORS file#

You use the AUTHORS file to specify the authorship of the repository. The Ansys Legal department has defined its format. You can add external contributors to this file on demand. Make sure that you adapt the project name on your specific repository’s AUTHORS file.

# This is the list of <PROJECT-NAME>'s significant contributors.
#
# This file does not necessarily list everyone who has contributed code.
#
# For contributions made under a Corporate CLA, the organization is
# added to this file.
#
# If you have contributed to the repository and want to be added to this file,
# submit a request.
#
#
ANSYS, Inc.

The CHANGELOG.md file#

You use the CHANGELOG.md file to collect new features, fixed bugs, documentation improvements, and new contributors. It provides a summary of the latest enhancements to the project.

# Changelog

## <pyproduct-library> <version X.Y.Z>, <Release Date YYYY-MM-DD>

### Bugs fixed

* Brief description of the bug. Link to the associated issue and pull request

### New features

* Brief description of the feature. Link to the associated issue and pull request.

### Doc improvements

* Brief description of the improvement. Link to the associated issue and pull request.

### Contributors

* <Name of the contributor> - <Email of the contributor>

## <pyproduct-library> <version X.Y.Z>, <Release Date YYYY-MM-DD>

The CODE_OF_CONDUCT.md file#

You use the CODE_OF_CONDUCT.md to specify how users, developers, and maintainers are to behave while working in the project. PyAnsys projects usually adopt the Contributor Covenant Code of Conduct, which is very popular across open source projects.

# Contributor covenant code of conduct

## Pledge

In the interest of fostering an open and welcoming environment,
all contributors and maintainers pledge to making participation
in the Ansys project and community a harassment-free experience
for everyone, regardless of age, body size, disability, ethnicity,
sex characteristics, gender identity and expression, level of
experience, education, socioeconomic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Standards

Examples of behavior that contribute to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual
  attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
  address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban temporarily or permanently any
contributor for other behaviors that they deem inappropriate, threatening,
offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project email
address, posting using an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Attribution

This code of conduct is adapted from the [Contributor Covenant][homepage],
version 1.4, available at
https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

The CONTRIBUTING.md file#

You use the CONTRIBUTING.md file to provide a quick entry-point for developers who are willing to contribute to the project. It usually provides references to this information:

  • Where the source code of the project is hosted.

  • Which steps must be followed to install the software in “development” mode.

  • Ways of contributing to the source code.

Ideally, the CONTRIBUTING.md file for a PyAnsys project should link to the PyAnsys developer’s guide for overall guidance.

# Contribute

Overall guidance on contributing to a PyAnsys library appears in the
[Contributing] topic in the *PyAnsys developer's guide*. Ensure that you
are thoroughly familiar with this guide before attempting to contribute to
X.

The following contribution information is specific to X.

[Contributing]: https://dev.docs.pyansys.com/how-to/contributing.html

<!-- In the previous content, replace X with the name of your library. For example, PyAEDT. -->
<!-- Begin content specific to your library here. -->

The CONTRIBUTORS.md file#

You use the CONTRIBUTORS.md file to list the contributors to the repository. Its purpose is to credit the authors for their individual contributions and provide a record of authorship for the codebase. Provide first and last names and links to GitHub usernames.

# Contributors

## Project Lead

* [First Last](https://github.com/ghusername)

## Individual Contributors

* [First Last](https://github.com/ghusername)

The LICENSE file#

The LICENSE file provides the legal framework for the software. PyAnsys projects must use the MIT License. Here is the template:

MIT License

Copyright (c) <YEAR> ANSYS, Inc. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

Caution

Just because a software does not ship with a LICENSE file, it does not mean it is free or open source. If you need to use unlicensed software, contact its development team so that they can provide you with the correct license.

The README file#

Each PyAnsys library must have a README file in the root directory.

The preferred format of this file is reStructuredText Markup Syntax, although you can also use Markdown Syntax. While Markdown syntax has better GitHub support, you can reuse ReStructuredText (RST) files within Sphinx documentation. For more information, see README.rst files.

The README file should at the minimum contain these elements:

  • PyAnsys library title

  • General description

  • Installation instructions (using pip install and git clone) but only if the library reuses README file content in its documentation

Note

While older projects tend to reuse content in their README.rst files in the main index.rst files in their doc/source directories, newer projects do not. Instead, they provide a bulleted list with documentation links and descriptions in their “”README`` files. In the main index.rst files for their documentation, they then use a grid of cards to visually explain and link to documentation sections. This keeps the README file focused on why you might want to explore the library and lets you quickly view documentation sections of interest.

The README.rst file is also reused within the project file metadata. It is usually included in the long-description field.

The pyproject.toml file#

PEP 518 introduced the use of a project file named pyproject.toml. This file is mandatory because it allows pip to resolve the requirements for building the library. The following tabs expose the [build-system] section for build-system backend tools commonly used in the Python ecosystem:

[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
[build-system]
requires = ["flit_core >=3.2,<4"]
build-backend = "flit_core.buildapi"

[project]
# Check https://flit.readthedocs.io/en/latest/pyproject_toml.html for all available sections
name = "Py<Product> <Library>"
version = "<version>"
description = "A Python wrapper for Ansys <Product> <Library>"
readme = "README.rst"
requires-python = ">=3.<minor>"
license = {file = "LICENSE"}
authors = [
    {name = "ANSYS, Inc.", email = "pyansys.core@ansys.com"},
]
maintainers = [
    {name = "PyAnsys developers", email = "pyansys.maintainers@ansys.com"},
]

classifiers = [
    "Development Status :: 4 - Beta",
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]
dependencies = [
    "importlib-metadata >=4.0",
]

[tool.flit.module]
name = "ansys.<product>.<library>"

[project.urls]
Source = "https://github.com/ansys/py<product>-<library>"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
# Check https://python-poetry.org/docs/pyproject/ for all available sections
name = "Py<Product> <Library>"
version = "<version>"
description = "A Python wrapper for <Product> <Library>"
license = "MIT"
authors = ["ANSYS, Inc. <pyansys.core@ansys.com>"]
maintainers = ["PyAnsys developers <pyansys.maintainers@ansys.com>"]
readme = "README.rst"
repository = "https://github.com/ansys/py<product>-<library>"
classifiers = [
    "Development Status :: 4 - Beta",
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]
packages = [
    { include = "ansys", from = "src" },
]

[tool.poetry.dependencies]
python = ">=3.<minor>"
importlib-metadata = {version = "^4.0", python = "<3.8"}

The setup.py file#

For a long time, Python developers used the setup.py file to build and distribute their libraries. Unlike a static pyproject.toml file, the setup.py file is a Python script. This means that Python code is interpreted when building the library. This approach supports customizing the build process but can also introduce security issues.

Note

The setup.py file is only compatible with Setuptools, which is why you should consider using a pyproject.toml file instead.

While you can use a setup.cfg file to specify the metadata and packages, the setup.py file must also be present. For more information, see these pages in the Setuptools documentation:

As a minimum configuration for a PyAnsys project, you can use this setup.py template:

"""Installation file for ansys-mapdl-core."""

from setuptools import find_namespace_packages, setup

setup(
    name="ansys-<product>-<library>",
    packages=find_namespace_packages(where="src", include="ansys*"),
    package_dir={"": "src"},
    version="<version>",
    description="<Short description of the package>",
    long_description=open("README.rst").read(),
    license="MIT",
    author="ANSYS, Inc.",
    author_email="pyansys.core@ansys.com",
    maintainer="PyAnsys developers",
    maintainer_email="pyansys.maintainers@ansys.com",
    classifiers=[
        "Development Status :: 4 - Beta",
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    url="<https://github.com/ansys/py<product>-<library>",
    python_requires=">=3.<minor>",
    install_requires=["importlib-metadata >=4.0"],
)