Contribute to plone.api#

This section describes how to contribute to the plone.api project. It extends Contributing to Plone.

Prerequisites#

Prepare your system by installing prerequisites.

System libraries#

You need to install system libraries, as described in Prerequisites, with the exception of GNU make.

tox#

tox automates and standardizes testing in Python. Install tox into your Python user space with the following command.

python -m pip install --user tox

pre-commit#

plone.api uses pre-commit to automate code quality checks before every commit.

Install pre-commit either with your system package manager. Alternatively you can install pre-commit into your Python user.

python -m pip install --user pre-commit

Once installed, set up the git hook scripts to run on every commit.

pre-commit install

Create development environment#

After satisfying the prerequisites, you are ready to create your development environment. plone.api uses tox as a wrapper around coredev.buildout to simplify development, whereas Plone core uses coredev.buildout directly.

Start by changing your working directory to your project folder, and download the latest plone.api source code.

cd <your_project_folder>
git clone https://github.com/plone/plone.api.git

Next go into the newly created directory, and build your environment.

cd plone.api
tox

Go make some tea while tox runs all tasks listed by issuing the command tox -l.

Open tox.ini in your code editor to see all configured commands and what they do. Some helpful tox commands are shown below.

tox -e py39-plone-60  # run all tests for Python 3.9 and Plone 6
tox -e plone6docs     # build documentation
tox -e livehtml       # build, serve, and reload changes to documentation
tox -l                # list all tox environments

git#

Use the following git branches when contributing to plone.api.

feature branches

All development for a new feature or bug fix must be done on a new branch.

master

Pull requests should be made from a feature branch against the master branch. When features and bug fixes are complete and approved, they are merged into the master branch.

See also

Work with git

Continuous integration#

plone.api uses GitHub workflows for continuous integration. On every push to the master branch, GitHub runs its workflows for all tests and code quality checks. GitHub workflows are configured in the directory .github/workflows at the root of this package.

Documentation#

For every feature change or addition to plone.api, you must add documentation of it. plone.api uses MyST for documentation syntax.

After adding or modifying documentation, you can build the documentation with the following command.

tox -e plone6docs

Alternatively, you can automatically reload changes to the documentation as you edit it in a web browser.

tox -e livehtml

The plone.api documentation is automatically generated from the documentation source files when its submodule is updated in the main Plone documentation repository.

Add a function to an existing module#

This section describes how to add a new function foo to plone.api.

The function would go in the module plone.api.content, located in the file src/plone/api/content.py.

@mutually_exclusive_parameters('path', 'UID')
@at_least_one_of('path', 'UID')
def foo(path=None, UID=None):
    """Do foo.

    :param path: Path to the object we want to get,
        relative to the portal root.
    :type path: string

    :param UID: UID of the object we want to get.
    :type UID: string

    :returns: String
    :raises:
        :class:`~plone.api.exc.MissingParameterError`,
        :class:`~plone.api.exc.InvalidParameterError`
    :Example: :ref:`content-foo-example`
    """
    return "foo"

Add documentation in docs/api/content.md. Narrative documentation should describe what your function does.

You should also write some tests in code blocks. TestCase methods, such as self.assertEqual(), are available in doctests. See unittest.TestCase assert methods for all available methods. The file is linked in /src/plone/api/tests/doctests/, which includes the doctests in plone.api's test setup. The package manuel allows you to write doctests as common Python code in code blocks.

The following example shows narrative documentation and doctests.

(content-foo-example)=

## Get the foo of an object

You can use the {meth}`api.content.foo` function to get the `foo` of an object.

```python
from plone import api
blog_foo = api.content.foo(path="/plone/blog")
```

% invisible-code-block: python
%
% self.assertEqual(blog_foo,"foo")

Code blocks are rendered in documentation.

```python
from plone import api
blog_foo = api.content.foo(path="/plone/blog")
```

Invisible code blocks are not rendered in documentation and can be used for tests.

% invisible-code-block: python
%
% self.assertEqual(blog_foo,"foo")

Invisible code blocks are also handy for enriching the namespace without cluttering the narrative documentation.

% invisible-code-block: python
%
% portal = api.portal.get()
% image = api.content.create(type='Image', id='image', container=portal)
% blog = api.content.create(type='Link', id='blog', container=portal)

Functions and examples in documentation are mutually referenced. The function references the narrative documentation via the label content-foo-example. The narrative documentation references the API function documentation via {meth}`api.content.foo`. The documentation is rendered with a link from the API reference to the narrative documentation, which in turn links back to the API reference.