Skip to content

Commit 900af61

Browse files
committed
Merge branch 'allowablepixels' of github.com:Open-EO/openeo-python-client into allowablepixels
2 parents 751c733 + ba14523 commit 900af61

22 files changed

Lines changed: 724 additions & 56 deletions

File tree

CHANGELOG.md

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

1010
### Added
1111

12+
- `openeo.testing.io.TestDataLoader`: unit test utility to compactly load (and optionally preprocess) tests data (text/JSON/...)
13+
- `openeo.Connection`: automatically retry API requests on `429 Too Many Requests` HTTP errors, with appropriate delay if possible ([#441](https://github.com/Open-EO/openeo-python-client/issues/441))
14+
1215
### Changed
1316

1417
- `DataCube.apply_dimension()`: not explicitly specifying the `dimension` argument is deprecated and will trigger warnings ([#774](https://github.com/Open-EO/openeo-python-client/issues/774))

Jenkinsfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ pythonPipeline {
2323
"PYTEST_DEBUG_TEMPROOT=pytest-tmp",
2424
]
2525
pre_test_script = 'pre_test.sh'
26+
enable_uv = true
2627
}

docs/basics.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ and observations are filtered out:
317317

318318
.. image:: _static/images/basics/evi-masked-composite.png
319319

320-
.. _aggregate-spatial-evi
320+
.. _aggregate-spatial-evi:
321321

322322
Aggregated EVI timeseries
323323
===========================

docs/conf.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
'sphinx.ext.viewcode',
4242
'sphinx.ext.doctest',
4343
'myst_parser',
44+
"sphinx.ext.intersphinx",
4445
]
4546

4647
import sphinx_autodoc_typehints
@@ -194,3 +195,13 @@
194195
author, 'openeo', 'One line description of project.',
195196
'Miscellaneous'),
196197
]
198+
199+
200+
# Mapping for external documentation
201+
intersphinx_mapping = {
202+
"python": ("https://docs.python.org/3", None),
203+
"numpy": ("https://numpy.org/doc/stable/", None),
204+
"xarray": ("https://docs.xarray.dev/en/stable/", None),
205+
"pandas": ("https://pandas.pydata.org/pandas-docs/stable/", None),
206+
"urllib3": ("https://urllib3.readthedocs.io/en/stable/", None),
207+
}

docs/cookbook/job_manager.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.. _job-manager
1+
.. _job-manager:
22

33
====================================
44
Multi Backend Job Manager

docs/datacube_construction.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ TODO
200200

201201

202202
.. _multi-result-process-graphs:
203+
203204
Building process graphs with multiple result nodes
204205
===================================================
205206

docs/udf.rst

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -374,11 +374,10 @@ the datacube.
374374
375375
376376
.. warning::
377-
378-
The ``apply_neighborhood`` is the most versatile, but also most complex process. Make sure to keep an eye on the dimensions
379-
and the shape of the DataArray returned by your UDF. For instance, a very common error is to somehow 'flip' the spatial dimensions.
380-
Debugging the UDF locally can help, but then you will want to try and reproduce the input that you get also on the backend.
381-
This can typically be achieved by using logging to inspect the DataArrays passed into your UDF backend side.
377+
The ``apply_neighborhood`` is the most versatile, but also most complex process. Make sure to keep an eye on the dimensions
378+
and the shape of the DataArray returned by your UDF. For instance, a very common error is to somehow 'flip' the spatial dimensions.
379+
Debugging the UDF locally can help, but then you will want to try and reproduce the input that you get also on the backend.
380+
This can typically be achieved by using logging to inspect the DataArrays passed into your UDF backend side.
382381

383382

384383

openeo/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.42.0a1"
1+
__version__ = "0.42.0a2"

openeo/extra/job_management/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
import shapely.errors
3030
import shapely.geometry.base
3131
import shapely.wkt
32-
from requests.adapters import HTTPAdapter, Retry
32+
from requests.adapters import HTTPAdapter
33+
from urllib3.util import Retry
3334

3435
from openeo import BatchJob, Connection
3536
from openeo.internal.processes.parse import (
@@ -284,7 +285,7 @@ def _make_resilient(connection):
284285
503 Service Unavailable
285286
504 Gateway Timeout
286287
"""
287-
# TODO: refactor this helper out of this class and unify with `openeo_driver.util.http.requests_with_retry`
288+
# TODO: migrate this to now built-in retry configuration of `Connection` or `openeo.util.http.retry_adapter`?
288289
status_forcelist = [500, 502, 503, 504]
289290
retries = Retry(
290291
total=MAX_RETRIES,

openeo/rest/_connection.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
from typing import Iterable, Optional, Union
66

77
import requests
8+
import urllib3.util
89
from requests import Response
910
from requests.auth import AuthBase
1011

1112
import openeo
1213
from openeo.rest import OpenEoApiError, OpenEoApiPlainError, OpenEoRestError
1314
from openeo.rest.auth.auth import NullAuth
1415
from openeo.util import ContextTimer, ensure_list, str_truncate, url_join
16+
from openeo.utils.http import HTTP_502_BAD_GATEWAY, session_with_retries
1517

1618
_log = logging.getLogger(__name__)
1719

@@ -26,15 +28,22 @@ class RestApiConnection:
2628
def __init__(
2729
self,
2830
root_url: str,
31+
*,
2932
auth: Optional[AuthBase] = None,
3033
session: Optional[requests.Session] = None,
3134
default_timeout: Optional[int] = None,
3235
slow_response_threshold: Optional[float] = None,
36+
retry: Union[urllib3.util.Retry, dict, bool, None] = None,
3337
):
3438
self._root_url = root_url
3539
self._auth = None
3640
self.auth = auth or NullAuth()
37-
self.session = session or requests.Session()
41+
if session:
42+
self.session = session
43+
elif retry is not False:
44+
self.session = session_with_retries(retry=retry)
45+
else:
46+
self.session = requests.Session()
3847
self.default_timeout = default_timeout or DEFAULT_TIMEOUT
3948
self.default_headers = {
4049
"User-Agent": "openeo-python-client/{cv} {py}/{pv} {pl}".format(
@@ -165,7 +174,7 @@ def _raise_api_error(self, response: requests.Response):
165174
_log.warning(f"Failed to parse API error response: [{status_code}] {text!r} (headers: {response.headers})")
166175

167176
# TODO: eliminate this VITO-backend specific error massaging?
168-
if status_code == 502 and "Proxy Error" in text:
177+
if status_code == HTTP_502_BAD_GATEWAY and "Proxy Error" in text:
169178
error_message = (
170179
"Received 502 Proxy Error."
171180
" This typically happens when a synchronous openEO processing request takes too long and is aborted."

0 commit comments

Comments
 (0)