Skip to content

Multi Package Projects

Benny Lutati edited this page Sep 9, 2021 · 4 revisions

There are several situations where dividing your project into several sub-packages is a good practice. For example, say that we are building a library that can also act as a standalone tool, we want to provide both programmatic api access and cli access. If we build it in a single package, the programmatic api consumer will have to also depend on the libraries that are requires for the cli even though they doesn't needs it. Splitting the package into two packages one for the library and one for the cli (which requires the library internally) allows the api user to depend only on the library while a cli user can depend on the cli package.

In this document, we will refer to a project that contains several sub-packages as a multi-package project. Relaxed Poetry (RP) has a support for such projects which makes managing them a lot easier.

Multi-Package Project

A multi-package project is a directory that contains a pyproject.toml with the following table:

# pyproject.toml

[tool.relaxed-poetry.sub-projects]
sub-project-1 = 'path-to-sub-project-1'
sub-project-2 = 'path-to-sub-project-2'
# ...

This directory defines the "parent" project for all the given sub-projects.

ℹ️ While you can supply any path to a sub-project, it is advisable to have it nested inside the multi-package project path, and specify it relative to the multi-project location.

When invoking the rp cli on a parent project its behavior is modified as follows:

  • install, update, build, and publish commands are propagated to each of the sub-projects
  • config, new, and init will act normally
  • The rest of the commands are available only if the parent is not a container-only parent project.

Container-only parent projects

Sometimes, a parent project is only required in order to contain it's sub-projects and it is not representing a package by itself. In such case there is no need to create or manage a virtual-environment for it. To indicate that the parent project is such a container just make sure it does not have a [tool.poetry.dependencies] table.

Sub-project

Sub-projects are just a regular relaxed-poetry projects and non-container parent projects, if the sub-project is located in a directory that cannot be found inside a parent project directory (in other words it is not nested inside a parent project) then the parent project must be defined in the pyproject toml as follows:

# pyproject.toml

[tool.relaxed-poetry]
parent-project = 'path-to-parent-project'

ℹ️ sub project can be itself, a multi-package project

Sibling dependencies

A sub-project can depend on its sibling using a sibling dependency:

# pyproject.toml

[tool.poetry.dependencies]
sibling-1 = { sibling=true, version='^1.2.3' }

The dependency work similar to path dependency with develop=true but when building a package the sub project will depend on the given version.

Non-container parent project are also considered as sub-projects and therefore can also depend on siblings.

ℹ️ You don't have to specify the version, if you don't it defaults to ^<actual sibling version>, where actual sibling version is taken from its pyproject.toml file.

Shared configuration, properties and build profiles

Any configuration that is added local to the parent project is seen as the default by the sub-project. Like any default configuration, its value can be overridden if specified directly in the sub-project.

Any property that is defined in the parent project is seen in any of the sub project and can be overridden if assigned a new value in the [tool.relaxed-poetry.properties] table. Similarly any profile that exists in the parent (automatic and manual) is available in the sub-project.

Clone this wiki locally