How to add custom OpenMDAO modules to FAST-OAD as a plugin

Once you have created your custom modules for FAST-OAD, you may want to share them with other users, which can be done in two ways:

  • Providing your code so they can copy it on their computer and have them set their custom_modules field accordingly in their FAST-OAD configuration file.

  • Packaging your code as a FAST-OAD plugin and have them install it through pip or equivalent. This is the subject of current chapter.

A FAST-OAD plugin can provide additional FAST-OAD modules, Jupyter notebooks and configuration files:

Plugin structure

In your source folder, a typical plugin structure would be like this:

my_package/
├── __init__.py
├── configurations/
│   ├── __init__.py
│   ├── configuration_1.yaml
│   └── configuration_2.yaml
├── models/
│   ├── __init__.py
│   ├── my_model.py
│   └── some_subpackage/
│       ├── __init__.py
│       └── some_more_code.py
└── notebooks/
    ├── __init__.py
    ├── any_data/
    │   ├── __init__.py
    │   └── some_data.xml
    ├── awesome_notebook.ipynb
    └── good_notebook.ipynb

As shown above, the expected structure is composed of Python packages, i.e. every folder should contain a __init__.py file, even if it contains only non-Python files (e.g. data for notebooks).

The root folder can be anywhere in your project structure, since plugin declaration will point to its location.

Expected folders in a plugin package are:

  • models: contains Python code where FAST-OAD modules are registered.

  • configurations: contains only configuration files in YAML format. No sub-folder is allowed. These configuration files will be usable through command line or API method generate_configuration_file().

  • notebooks: contains any number of Jupyter notebooks and associated data, that will be made available to users through command line.

Any of these folders is optional. Any other folder will be ignored.

Plugin packaging

To make your custom modules usable as a FAST-OAD plugin, you have to package them and declare your package as a plugin with fastoad.plugins as plugin group name.

Here under is a brief tutorial about these operations using Poetry.

Note

If you are not familiar with Python packaging, it is recommended to look at this tutorial first. It presents the important steps and notions of the packaging process, and the “classic” way using setuptools. And if you want to stick to setuptools, check this page for details about plugin declaration.

Plugin declaration

For the example, let’s consider that your project contains the package star_trek.drives, and that your project structure contains:

src/
├── star_trek/
│   ├── __init__.py
│   ├── drives/
│   │   ├── __init__.py
│   │   ├── configurations/
│   │   ├── models/
│   │   └── notebooks/
│   └── ...
└── ...

As previously stated, your folder src/star_trek/drives does not have to contain all of the folders models, configurations nor notebooks.

Assuming you project contains the package star_trek.drives that contains models you want to share, you can declare your plugin in your pyproject.toml file with:

...

[tool.poetry]
# Tells location of sources
packages = [
    { include = "star_trek", from = "src" },
]

...

# Plugin declaration
[tool.poetry.plugins."fastoad.plugins"]
"ST_plugin" = "star_trek.drives"

...

Note

It is discouraged to declare several FAST-OAD plugins for a same project.

Once your pyproject.toml is set, you can do poetry install. Besides installing your project dependencies, it will make your models locally available (i.e. you could use their identifiers in your FAST-OAD configuration file without setting the custom_modules field)

Building

You can build your package with the command line poetry build. Let’s assume your pyproject.toml file is configured so that your project name is ST_drive_models, as below:

...

[tool.poetry]
name = "ST_drive_models"
version = "1.0.0"

# Tells location of sources
packages = [
    { include = "star_trek", from = "src" },
]

...

# Specify that Poetry is used for building the package
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

...

# Plugin declaration
[tool.poetry.plugins."fastoad.plugins"]
"ST_plugin" = "star_trek.drives"
...

The command poetry build will create a dist folder with two files:

ST_drive_models-1.0.0.tar.gz and ST_drive_models-1.0.0-py3-none-any.whl (or something like this).

You may then have sent any of those two files to another user, who may then install your models using pip with:

$ pip install ST_drive_models-1.0.0-py3-none-any.whl  # or ST_drive_models-1.0.0.tar.gz

Publishing

Once you have built your package, you may publish it on a a package repository. poetry publish will publish your package on PyPI, provided that you have correctly set your account.

Note

Publishing on PyPI requires a valid account, and also that the chosen package name (defined by name field in the pyproject.toml file) is unused, or already associated to your account.

Poetry can also publish to another destination.

Please see here for detailed information.