Skip to content

Commit 07b869c

Browse files
committed
Issue #390 add ProcessBuilder and openeo.processes docs
1 parent 05b9f06 commit 07b869c

12 files changed

+931
-136
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2626
([#386](https://github.com/Open-EO/openeo-python-client/issues/386)).
2727
The (experimental) `fit_class_random_forest()` and `fit_regr_random_forest()` methods
2828
moved accordingly to the `VectorCube` class.
29+
- Improved documentation on `openeo.processes` and `ProcessBuilder`
30+
([#390](https://github.com/Open-EO/openeo-python-client/issues/390)).
2931

3032
### Removed
3133

docs/_static/custom.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,7 @@ pre {
104104
font-size: 75%;
105105
padding: 0 1ex;
106106
}
107+
108+
nav.contents.local {
109+
border: none;
110+
}

docs/api-processbuilder.rst

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
.. FYI this file is intended to be inlined (with "include" RST directive)
2+
in the ProcessBuilder class doc block,
3+
which in turn is covered with autodoc/automodule from api-processes.rst.
4+
5+
6+
The :py:class:`ProcessBuilder <openeo.processes.ProcessBuilder>` class
7+
is a helper class that implements
8+
(much like the :ref:`openEO process functions <openeo_processes_functions>`)
9+
each openEO process as a method.
10+
On top of that it also adds syntactic sugar to support Python operators as well
11+
(e.g. ``+`` is translated to the ``add`` process).
12+
13+
.. attention::
14+
As normal user, you should never create a
15+
:py:class:`ProcessBuilder <openeo.processes.ProcessBuilder>` instance
16+
directly.
17+
18+
You should only interact with this class inside a callback
19+
function/lambda while building a child callback process graph
20+
as discussed at :ref:`child_callback_callable`.
21+
22+
23+
For example, let's start from this simple usage snippet
24+
where we want to reduce the temporal dimension
25+
by taking the temporal mean of each timeseries:
26+
27+
.. code-block:: python
28+
29+
def my_reducer(data):
30+
return data.mean()
31+
32+
cube.reduce_dimension(reducer=my_reducer, dimension="t")
33+
34+
Note that this ``my_reducer`` function has a ``data`` argument,
35+
which conceptually corresponds to an array of pixel values
36+
(along the temporal dimension).
37+
However, it's important to understand that the ``my_reducer`` function
38+
is actually *not evaluated when you execute your process graph*
39+
on an openEO back-end, e.g. as a batch jobs.
40+
Instead, ``my_reducer`` is evaluated
41+
*while building your process graph client-side*
42+
(at the time you execute that ``cube.reduce_dimension()`` statement to be precise).
43+
This means that that ``data`` argument is actually not a concrete array of EO data,
44+
but some kind of *virtual placeholder*,
45+
a :py:class:`ProcessBuilder <openeo.processes.ProcessBuilder>` instance,
46+
that keeps track of the operations you intend to do on the EO data.
47+
48+
To make that more concrete, it helps to add type hints
49+
which will make it easier to discover what you can do with the argument
50+
(depending on which editor or IDE you are using):
51+
52+
.. code-block:: python
53+
54+
from openeo.processes import ProcessBuilder
55+
56+
def my_reducer(data: ProcessBuilder) -> ProcessBuilder:
57+
return data.mean()
58+
59+
cube.reduce_dimension(reducer=my_reducer, dimension="t")
60+
61+
62+
Because :py:class:`ProcessBuilder <openeo.processes.ProcessBuilder>` methods
63+
return new :py:class:`ProcessBuilder <openeo.processes.ProcessBuilder>` instances,
64+
and because it support syntactic sugar to use Python operators on it,
65+
and because :ref:`openeo.process functions <openeo_processes_functions>`
66+
also accept and return :py:class:`ProcessBuilder <openeo.processes.ProcessBuilder>` instances,
67+
we can mix methods, functions and operators in the callback function like this:
68+
69+
.. code-block:: python
70+
71+
from openeo.processes import ProcessBuilder, cos
72+
73+
def my_reducer(data: ProcessBuilder) -> ProcessBuilder:
74+
return cos(data.mean()) + 1.23
75+
76+
cube.reduce_dimension(reducer=my_reducer, dimension="t")
77+
78+
or compactly, using an anonymous lambda expression:
79+
80+
.. code-block:: python
81+
82+
from openeo.processes import cos
83+
84+
cube.reduce_dimension(
85+
reducer=lambda data: cos(data.mean())) + 1.23,
86+
dimension="t"
87+
)

docs/api-processes.rst

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
=========================
2+
API: ``openeo.processes``
3+
=========================
4+
5+
The ``openeo.processes`` module contains building blocks and helpers
6+
to construct so called "child callbacks" for openEO processes like
7+
:py:meth:`openeo.rest.datacube.DataCube.apply` and
8+
:py:meth:`openeo.rest.datacube.DataCube.reduce_dimension`,
9+
as discussed at :ref:`child_callback_callable`.
10+
11+
.. note::
12+
The contents of the ``openeo.processes`` module is automatically compiled
13+
from the official openEO process specifications.
14+
Developers that want to fix bugs in, or add implementations to this
15+
module should not touch the file directly, but instead address it in the
16+
upstream `openeo-processes <https://github.com/Open-EO/openeo-processes>`_ repository
17+
or in the internal tooling to generate this file.
18+
19+
20+
.. contents:: Sections:
21+
:depth: 1
22+
:local:
23+
:backlinks: top
24+
25+
26+
.. _openeo_processes_functions:
27+
28+
Functions in ``openeo.processes``
29+
---------------------------------
30+
31+
The ``openeo.processes`` module implements (at top-level)
32+
a regular Python function for each openEO process
33+
(not only the official stable ones, but also experimental ones in "proposal" state).
34+
35+
These functions can be used directly as child callback,
36+
for example as follows:
37+
38+
.. code-block:: python
39+
40+
from openeo.processes import absolute, max
41+
42+
cube.apply(absolute)
43+
cube.reduce_dimension(max, dimension="t")
44+
45+
46+
Note how the signatures of the parent :py:class:`DataCube <openeo.rest.datacube.DataCube>` methods
47+
and the callback functions match up:
48+
49+
- :py:meth:`DataCube.apply() <openeo.rest.datacube.DataCube.apply>`
50+
expects a callback that receives a single numerical value,
51+
which corresponds to the parameter signature of :py:func:`openeo.processes.absolute`
52+
- :py:meth:`DataCube.reduce_dimension() <openeo.rest.datacube.DataCube.reduce_dimension>`
53+
expects a callback that receives an array of numerical values,
54+
which corresponds to the parameter signature :py:func:`openeo.processes.max`
55+
56+
57+
.. automodule:: openeo.processes
58+
:members:
59+
:exclude-members: ProcessBuilder, process, _process
60+
61+
62+
``ProcessBuilder`` helper class
63+
--------------------------------
64+
65+
.. FYI the ProcessBuilder docs are provided through its doc block
66+
with an RST "include" of "api-processbuilder.rst"
67+
68+
.. automodule:: openeo.processes
69+
:members: ProcessBuilder

docs/api.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
===
2-
API
3-
===
1+
=============
2+
API (General)
3+
=============
44

55
High level Interface
66
--------------------

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ Table of contents
6060
configuration
6161
cookbook/index
6262
api
63+
api-processes
6364
process_mapping
6465
development
6566
best_practices

docs/process_mapping.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import datetime
1010
import sys
1111
from textwrap import dedent
12+
import importlib
1213

1314
from openeo.internal.documentation import _process_registry
1415

@@ -38,6 +39,14 @@ def main():
3839
* - openEO process
3940
- openEO Python Client Method
4041
"""))
42+
# Import some submodules to make sure `_process_registry` is populated
43+
for mod in [
44+
"openeo.rest.datacube",
45+
"openeo.rest.vectorcube",
46+
"openeo.rest.mlmodel",
47+
"openeo.processes",
48+
]:
49+
importlib.import_module(mod)
4150

4251
for process_id in sorted(_process_registry.keys()):
4352
functions = [x[0] for x in _process_registry[process_id]]

0 commit comments

Comments
 (0)