Skip to content

Commit 0860840

Browse files
committed
Merge remote-tracking branch 'origin/master' into hv_issue719-job-manager-threaded-job-start
2 parents 48c4565 + 0cf3bdd commit 0860840

File tree

75 files changed

+630
-96
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+630
-96
lines changed

CHANGELOG.md

+14-1
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
### Changed
13+
14+
### Removed
15+
16+
### Fixed
17+
18+
19+
## [0.40.0] - 2025-04-14
20+
21+
### Added
22+
1223
- `sar_backscatter`: try to retrieve coefficient options from backend ([#693](https://github.com/Open-EO/openeo-python-client/issues/693))
24+
- Improve error message when OIDC provider is unavailable ([#751](https://github.com/Open-EO/openeo-python-client/issues/751))
25+
- Added `on_response_headers` argument to `DataCube.download()` and related to handle (e.g. `print`) the response headers ([#560](https://github.com/Open-EO/openeo-python-client/issues/560))
1326

1427
### Changed
1528

16-
### Removed
29+
- When the bands provided to `Connection.load_stac(..., bands=[...])` do not fully match the bands the client extracted from the STAC metadata, a warning will be triggered, but the provided band names will still be used during the client-side preparation of the process graph. This is a pragmatic approach to bridge the gap between differing interpretations of band detection in STAC. Note that this might produce process graphs that are technically invalid and might not work on other backends or future versions of the backend you currently use. It is recommended to consult with the provider of the STAC metadata and openEO backend on the correct and future-proof band names. ([#752](https://github.com/Open-EO/openeo-python-client/issues/752))
1730

1831
### Fixed
1932

docs/basics.rst

+6-5
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ We load an initial small spatio-temporal slice (a data cube) as follows:
126126
sentinel2_cube = connection.load_collection(
127127
"SENTINEL2_L2A",
128128
spatial_extent={"west": 5.14, "south": 51.17, "east": 5.17, "north": 51.19},
129-
temporal_extent = ["2021-02-01", "2021-04-30"],
130-
bands=["B02", "B04", "B08"]
129+
temporal_extent=["2021-02-01", "2021-04-30"],
130+
bands=["B02", "B04", "B08"],
131131
)
132132
133133
Note how we specify a the region of interest, a time range and a set of bands to load.
@@ -279,8 +279,8 @@ First, we load a new ``SENTINEL2_L2A`` based data cube with this specific ``SCL`
279279
s2_scl = connection.load_collection(
280280
"SENTINEL2_L2A",
281281
spatial_extent={"west": 5.14, "south": 51.17, "east": 5.17, "north": 51.19},
282-
temporal_extent = ["2021-02-01", "2021-04-30"],
283-
bands=["SCL"]
282+
temporal_extent=["2021-02-01", "2021-04-30"],
283+
bands=["SCL"],
284284
)
285285
286286
Now we can use the compact "band math" feature again to build a
@@ -362,7 +362,7 @@ Building on the experience from previous sections, we first build a masked EVI c
362362
sentinel2_cube = connection.load_collection(
363363
"SENTINEL2_L2A",
364364
spatial_extent={"west": 5.14, "south": 51.17, "east": 5.17, "north": 51.19},
365-
temporal_extent = ["2020-01-01", "2021-12-31"],
365+
temporal_extent=["2020-01-01", "2021-12-31"],
366366
bands=["B02", "B04", "B08", "SCL"],
367367
)
368368
@@ -413,6 +413,7 @@ which we massage a bit more:
413413
from openeo.rest.conversions import timeseries_json_to_pandas
414414
415415
import json
416+
416417
with open("evi-aggregation.json") as f:
417418
data = json.load(f)
418419

docs/cookbook/job_manager.rst

+5-3
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,11 @@ Basic usage example with a remote process definition:
7777
7878
# Initialize job database from a dataframe,
7979
# with desired parameter values to fill in.
80-
df = pd.DataFrame({
81-
"start_date": ["2021-01-01", "2021-02-01", "2021-03-01"],
82-
})
80+
df = pd.DataFrame(
81+
{
82+
"start_date": ["2021-01-01", "2021-02-01", "2021-03-01"],
83+
}
84+
)
8385
job_db = create_job_db("jobs.csv").initialize_from_df(df)
8486
8587
# Create and run job manager,

docs/cookbook/localprocessing.rst

+9-6
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,12 @@ The following code snippet loads Sentinel-2 L2A data from a public STAC Catalog,
4848
>>> temporal_extent = ["2019-01-01", "2019-06-15"]
4949
>>> bands = ["red"]
5050
>>> properties = {"eo:cloud_cover": dict(lt=50)}
51-
>>> s2_cube = local_conn.load_stac(url=url,
52-
... spatial_extent=spatial_extent,
53-
... temporal_extent=temporal_extent,
54-
... bands=bands,
55-
... properties=properties,
51+
>>> s2_cube = local_conn.load_stac(
52+
... url=url,
53+
... spatial_extent=spatial_extent,
54+
... temporal_extent=temporal_extent,
55+
... bands=bands,
56+
... properties=properties,
5657
... )
5758
>>> s2_cube.execute()
5859
<xarray.DataArray 'stackstac-08730b1b5458a4ed34edeee60ac79254' (time: 177,
@@ -94,6 +95,7 @@ With some sample data we can now check the STAC metadata for the local files by
9495
.. code:: python
9596
9697
from openeo.local import LocalConnection
98+
9799
local_data_folders = [
98100
"./openeo-localprocessing-data/sample_netcdf",
99101
"./openeo-localprocessing-data/sample_geotiff",
@@ -162,10 +164,11 @@ We can perform the same example using data provided by STAC Collection:
162164
.. code:: python
163165
164166
from openeo.local import LocalConnection
167+
165168
local_conn = LocalConnection("./")
166169
167170
url = "https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a"
168-
spatial_extent = {"east": 11.40, "north": 46.52, "south": 46.46, "west": 11.25}
171+
spatial_extent = {"east": 11.40, "north": 46.52, "south": 46.46, "west": 11.25}
169172
temporal_extent = ["2022-06-01", "2022-06-30"]
170173
bands = ["red", "nir"]
171174
properties = {"eo:cloud_cover": dict(lt=80)}

docs/cookbook/tricks.rst

+6-4
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,13 @@ For example:
6969
.. code-block:: python
7070
7171
# `execute` with raw JSON string
72-
connection.execute("""
72+
connection.execute(
73+
"""
7374
{
7475
"add": {"process_id": "add", "arguments": {"x": 3, "y": 5}, "result": true}
7576
}
76-
""")
77+
"""
78+
)
7779
7880
# `download` with local path to JSON file
7981
connection.download("path/to/my-process-graph.json")
@@ -99,7 +101,7 @@ where you could pass a *backend-side* path as ``geometries``, e.g.:
99101
100102
cube = cube.aggregate_spatial(
101103
geometries="/backend/path/to/geometries.json",
102-
reducer="mean"
104+
reducer="mean",
103105
)
104106
105107
The client would handle this by automatically adding a ``read_vector`` process
@@ -124,7 +126,7 @@ for example as follows:
124126
125127
cube = cube.aggregate_spatial(
126128
geometries=process("read_vector", filename="/backend/path/to/geometries.json"),
127-
reducer="mean"
129+
reducer="mean",
128130
)
129131
130132
Note that this is also works with older versions of the openEO Python client library.

docs/data_access.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ For example, to filter on the relative orbit number of SAR data:
274274
"SENTINEL1_GRD",
275275
...,
276276
properties={
277-
"relativeOrbitNumber": lambda x: x==116
277+
"relativeOrbitNumber": lambda x: x == 116,
278278
},
279279
)
280280

docs/development.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ we will use a concrete version ``0.8.0`` in the examples below.
246246
#. Create release commit:
247247

248248
A. **Drop the pre-release suffix** from the version string in ``openeo/_version.py``
249-
so that it just a "final" semantic versioning string, e.g. ``0.8.0``
249+
so that it is just a "final" semantic versioning string, e.g. ``0.8.0``
250250

251251
B. **Update CHANGELOG.md**: rename the "Unreleased" section title
252252
to contain version and date, e.g.::
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import xarray
2+
from scipy.signal import savgol_filter
3+
4+
from openeo.udf import XarrayDataCube
5+
6+
7+
def apply_datacube(cube: XarrayDataCube, context: dict) -> XarrayDataCube:
8+
"""
9+
Apply Savitzky-Golay smoothing to a timeseries datacube.
10+
This UDF preserves dimensionality, and assumes an input
11+
datacube with a temporal dimension 't' as input.
12+
"""
13+
array: xarray.DataArray = cube.get_array()
14+
filled = array.interpolate_na(dim="t")
15+
smoothed_array = savgol_filter(filled.values, 5, 2, axis=0)
16+
return XarrayDataCube(array=xarray.DataArray(smoothed_array, dims=array.dims, coords=array.coords))
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import numpy as np
2+
import xarray
3+
4+
from openeo.metadata import CollectionMetadata
5+
from openeo.udf import XarrayDataCube
6+
from openeo.udf.debug import inspect
7+
8+
9+
def apply_metadata(input_metadata: CollectionMetadata, context: dict) -> CollectionMetadata:
10+
11+
xstep = input_metadata.get("x", "step")
12+
ystep = input_metadata.get("y", "step")
13+
new_metadata = {
14+
"x": {"type": "spatial", "axis": "x", "step": xstep / 2.0, "reference_system": 4326},
15+
"y": {"type": "spatial", "axis": "y", "step": ystep / 2.0, "reference_system": 4326},
16+
"t": {"type": "temporal"},
17+
}
18+
return CollectionMetadata(new_metadata)
19+
20+
21+
def fancy_upsample_function(array: np.array, factor: int = 2) -> np.array:
22+
assert array.ndim == 3
23+
return array.repeat(factor, axis=-1).repeat(factor, axis=-2)
24+
25+
26+
def apply_datacube(cube: XarrayDataCube, context: dict) -> XarrayDataCube:
27+
array: xarray.DataArray = cube.get_array()
28+
29+
cubearray: xarray.DataArray = cube.get_array().copy() + 60
30+
31+
# We make prediction and transform numpy array back to datacube
32+
33+
# Pixel size of the original image
34+
init_pixel_size_x = cubearray.coords["x"][-1] - cubearray.coords["x"][-2]
35+
init_pixel_size_y = cubearray.coords["y"][-1] - cubearray.coords["y"][-2]
36+
37+
if cubearray.data.ndim == 4 and cubearray.data.shape[0] == 1:
38+
cubearray = cubearray[0]
39+
predicted_array = fancy_upsample_function(cubearray.data, 2)
40+
inspect(predicted_array, "test message")
41+
coord_x = np.linspace(
42+
start=cube.get_array().coords["x"].min(),
43+
stop=cube.get_array().coords["x"].max() + init_pixel_size_x,
44+
num=predicted_array.shape[-2],
45+
endpoint=False,
46+
)
47+
coord_y = np.linspace(
48+
start=cube.get_array().coords["y"].min(),
49+
stop=cube.get_array().coords["y"].max() + init_pixel_size_y,
50+
num=predicted_array.shape[-1],
51+
endpoint=False,
52+
)
53+
predicted_cube = xarray.DataArray(predicted_array, dims=["bands", "x", "y"], coords=dict(x=coord_x, y=coord_y))
54+
55+
return XarrayDataCube(predicted_cube)

docs/federation-extension.rst

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ using :py:meth:`OpenEoCapabilities.ext_federation_backend_details() <openeo.rest
3737
.. code-block:: python
3838
3939
import openeo
40+
4041
connection = openeo.connect(url=...)
4142
capabilities = connection.capabilities()
4243
print("Federated backends:", capabilities.ext_federation_backend_details())
@@ -57,6 +58,7 @@ and can be inspected as follows:
5758
.. code-block:: python
5859
5960
import openeo
61+
6062
connection = openeo.connect(url=...)
6163
collections = connection.list_collections()
6264
print("Number of collections:", len(collections))

0 commit comments

Comments
 (0)