Skip to content

Commit 77c3e87

Browse files
committed
openeo.UDF: automatically un-indent UDF code
1 parent abaa9ad commit 77c3e87

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
### Changed
1313

14+
- `openeo.UDF()`: automatically un-indent given UDF code ([#782](https://github.com/Open-EO/openeo-python-client/issues/782))
15+
1416
### Removed
1517

1618
### Fixed

openeo/rest/_datacube.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import logging
44
import pathlib
55
import re
6+
import textwrap
67
import typing
78
import uuid
89
import warnings
@@ -142,6 +143,10 @@ class UDF:
142143
Specifying the ``data`` argument is not necessary anymore, and actually deprecated.
143144
Added :py:meth:`from_file` to simplify loading UDF code from a file.
144145
See :ref:`old_udf_api` for more background about the changes.
146+
147+
.. versionchanged:: 0.43.0
148+
Automatically un-indent given UDF code,
149+
to simplify writing valid and properly formatted inline UDF code.
145150
"""
146151

147152
# TODO: eliminate dependency on `openeo.rest.connection` and move to somewhere under `openeo.internal`?
@@ -155,7 +160,9 @@ def __init__(
155160
data=None, # TODO #181 remove `data` argument
156161
version: Optional[str] = None,
157162
context: Optional[dict] = None,
163+
*,
158164
_source=None,
165+
auto_dedent: bool = True,
159166
):
160167
"""
161168
Construct a UDF object from given code string and other argument related to the ``run_udf`` process.
@@ -167,7 +174,8 @@ def __init__(
167174
:param context: optional additional UDF context data
168175
:param _source: (for internal use) source identifier
169176
"""
170-
# TODO: automatically dedent code (when literal string) ?
177+
if auto_dedent:
178+
code = textwrap.dedent(code)
171179
self.code = code
172180
self._runtime = runtime
173181
self.version = version

tests/rest/datacube/test_datacube100.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3841,6 +3841,46 @@ def test_apply_udf_basic(self, con100):
38413841
},
38423842
}
38433843

3844+
def test_apply_udf_auto_dedent(self, con100):
3845+
udf = openeo.UDF(
3846+
"""
3847+
import xarray
3848+
3849+
def apply_datacube(cube: xarray.DataArray, context: dict) -> xarray.DataArray:
3850+
cube.values = 0.0001 * cube.values
3851+
return cube
3852+
"""
3853+
)
3854+
cube = con100.load_collection("S2")
3855+
res = cube.apply(udf)
3856+
3857+
assert res.flat_graph()["apply1"]["arguments"] == {
3858+
"data": {"from_node": "loadcollection1"},
3859+
"process": {
3860+
"process_graph": {
3861+
"runudf1": {
3862+
"process_id": "run_udf",
3863+
"arguments": {
3864+
"data": {"from_parameter": "x"},
3865+
"runtime": "Python",
3866+
"udf": "\n".join(
3867+
[
3868+
"",
3869+
"import xarray",
3870+
"",
3871+
"def apply_datacube(cube: xarray.DataArray, context: dict) -> xarray.DataArray:",
3872+
" cube.values = 0.0001 * cube.values",
3873+
" return cube",
3874+
"",
3875+
]
3876+
),
3877+
},
3878+
"result": True,
3879+
}
3880+
},
3881+
},
3882+
}
3883+
38443884
def test_apply_udf_runtime_detection(self, con100, requests_mock):
38453885
udf = UDF("def foo(x):\n return x\n")
38463886
cube = con100.load_collection("S2")

0 commit comments

Comments
 (0)