Skip to content

Commit 082a2f5

Browse files
committed
Issue #611/#610 Introduce OpenEoCapabilities and deprecate RESTCapabilities
- Introduce openeo.rest.capabilities.OpenEoCapabilities and add to API docs - Deprecate openeo.rest.rest_capabilities.RESTCapabilities - Remove base class openeo.capabilities.Capabilities
1 parent 8d200c9 commit 082a2f5

File tree

8 files changed

+134
-116
lines changed

8 files changed

+134
-116
lines changed

CHANGELOG.md

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

1414
- Improved tracking of metadata changes with `resample_spatial` and `resample_cube_spatial` ([#690](https://github.com/Open-EO/openeo-python-client/issues/690))
1515
- Move `ComparableVersion` to `openeo.utils.version` (related to [#611](https://github.com/Open-EO/openeo-python-client/issues/611))
16+
- Deprecate `openeo.rest.rest_capabilities.RESTCapabilities` and introduce replacement `openeo.rest.capabilities.OpenEoCapabilities` ([#611](https://github.com/Open-EO/openeo-python-client/issues/611), [#610](https://github.com/Open-EO/openeo-python-client/issues/610))
1617

1718
### Removed
1819

20+
- Remove unnecessary base class `openeo.capabilities.Capabilities` [#611](https://github.com/Open-EO/openeo-python-client/issues/611)
21+
1922
### Fixed
2023

2124

docs/api.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ openeo.metadata
6363
:members: CollectionMetadata, BandDimension, SpatialDimension, TemporalDimension
6464

6565

66+
openeo.rest.capabilities
67+
------------------------
68+
69+
.. automodule:: openeo.rest.capabilities
70+
:members: OpenEoCapabilities
71+
72+
6673
openeo.api.process
6774
--------------------
6875

openeo/capabilities.py

Lines changed: 8 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,12 @@
1-
from __future__ import annotations
2-
3-
from abc import ABC
1+
import warnings
42

3+
from openeo.internal.warnings import UserDeprecationWarning
54
from openeo.utils.version import ApiVersionException, ComparableVersion
65

7-
__all__ = ["Capabilities", "ComparableVersion", "ApiVersionException"]
8-
9-
10-
class Capabilities(ABC):
11-
"""Represents capabilities of a connection / back end."""
12-
13-
# TODO Is this base class (still) useful?
14-
15-
def __init__(self, data):
16-
pass
17-
18-
def version(self):
19-
""" Get openEO version. DEPRECATED: use api_version instead"""
20-
# Field: version
21-
# TODO: raise deprecation warning here?
22-
return self.api_version()
23-
24-
def api_version(self) -> str:
25-
"""Get OpenEO API version."""
26-
raise NotImplementedError
27-
28-
@property
29-
def api_version_check(self) -> ComparableVersion:
30-
"""Helper to easily check if the API version is at least or below some threshold version."""
31-
api_version = self.api_version()
32-
if not api_version:
33-
raise ApiVersionException("No API version found")
34-
return ComparableVersion(api_version)
35-
36-
def list_features(self):
37-
""" List all supported features / endpoints."""
38-
# Field: endpoints
39-
pass
40-
41-
def has_features(self, method_name):
42-
""" Check whether a feature / endpoint is supported."""
43-
# Field: endpoints > ...
44-
pass
45-
46-
def currency(self):
47-
""" Get default billing currency."""
48-
# Field: billing > currency
49-
pass
6+
warnings.warn(
7+
message="Submodule `openeo.capabilities` is deprecated. Find `ComparableVersion` and related at `openeo.utils.version`.",
8+
category=UserDeprecationWarning,
9+
stacklevel=2,
10+
)
5011

51-
def list_plans(self):
52-
""" List all billing plans."""
53-
# Field: billing > plans
54-
pass
12+
__all__ = ["ComparableVersion", "ApiVersionException"]

openeo/rest/capabilities.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from typing import List, Optional, Union
2+
3+
from openeo.internal.jupyter import render_component
4+
from openeo.util import deep_get
5+
from openeo.utils.version import ApiVersionException, ComparableVersion
6+
7+
__all__ = ["OpenEoCapabilities"]
8+
9+
10+
class OpenEoCapabilities:
11+
"""Container of the openEO capabilities document of an openEO backend."""
12+
13+
def __init__(self, data: dict, url: Optional[str] = None):
14+
self.capabilities = data
15+
self.url = url
16+
17+
def get(self, key: str, default=None):
18+
return self.capabilities.get(key, default)
19+
20+
def deep_get(self, *keys, default=None):
21+
return deep_get(self.capabilities, *keys, default=default)
22+
23+
def api_version(self) -> Union[str, None]:
24+
"""Version number of the openEO API specification this back-end implements."""
25+
if "api_version" in self.capabilities:
26+
return self.capabilities.get("api_version")
27+
else:
28+
# Legacy/deprecated
29+
return self.capabilities.get("version")
30+
31+
@property
32+
def api_version_check(self) -> ComparableVersion:
33+
"""Helper to easily check if the API version is at least or below some threshold version."""
34+
api_version = self.api_version()
35+
if not api_version:
36+
raise ApiVersionException("No API version found")
37+
return ComparableVersion(api_version)
38+
39+
def supports_endpoint(self, path: str, method="GET") -> bool:
40+
"""Check if backend supports given endpoint"""
41+
return any(
42+
endpoint.get("path") == path and method.upper() in endpoint.get("methods", [])
43+
for endpoint in self.capabilities.get("endpoints", [])
44+
)
45+
46+
def currency(self) -> Union[str, None]:
47+
"""Get default billing currency."""
48+
return self.deep_get("billing", "currency", default=None)
49+
50+
def list_plans(self) -> List[dict]:
51+
"""List all billing plans."""
52+
return self.deep_get("billing", "plans", default=[])
53+
54+
def _repr_html_(self):
55+
return render_component("capabilities", data=self.capabilities, parameters={"url": self.url})

openeo/rest/connection.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@
7070
OidcRefreshTokenAuthenticator,
7171
OidcResourceOwnerPasswordAuthenticator,
7272
)
73+
from openeo.rest.capabilities import OpenEoCapabilities
7374
from openeo.rest.datacube import DataCube, InputDate
7475
from openeo.rest.graph_building import CollectionProperty
7576
from openeo.rest.job import BatchJob, RESTJob
7677
from openeo.rest.mlmodel import MlModel
77-
from openeo.rest.rest_capabilities import RESTCapabilities
7878
from openeo.rest.service import Service
7979
from openeo.rest.udp import Parameter, RESTUserDefinedProcess
8080
from openeo.rest.userfile import UserFile
@@ -927,13 +927,13 @@ def list_collection_ids(self) -> List[str]:
927927
"""
928928
return [collection['id'] for collection in self.list_collections() if 'id' in collection]
929929

930-
def capabilities(self) -> RESTCapabilities:
930+
def capabilities(self) -> OpenEoCapabilities:
931931
"""
932-
Loads all available capabilities.
932+
Fetch the openEO capabilities document.
933933
"""
934934
return self._capabilities_cache.get(
935935
"capabilities",
936-
load=lambda: RESTCapabilities(data=self.get('/', expected_status=200).json(), url=self._orig_url)
936+
load=lambda: OpenEoCapabilities(data=self.get("/", expected_status=200).json(), url=self._orig_url),
937937
)
938938

939939
def list_input_formats(self) -> dict:

openeo/rest/rest_capabilities.py

Lines changed: 11 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,15 @@
1-
from typing import List, Optional
1+
import warnings
22

3-
from openeo.capabilities import Capabilities
4-
from openeo.internal.jupyter import render_component
5-
from openeo.util import deep_get
3+
from openeo.internal.warnings import UserDeprecationWarning
4+
from openeo.rest.capabilities import OpenEoCapabilities
65

6+
warnings.warn(
7+
message="`RESTCapabilities` from `openeo.rest.rest_capabilities` is deprecated. Instead use `OpenEoCapabilities` from `openeo.rest.capabilities`.",
8+
category=UserDeprecationWarning,
9+
stacklevel=2,
10+
)
711

8-
class RESTCapabilities(Capabilities):
9-
"""Represents REST capabilities of a connection / back end."""
12+
__all__ = ["RESTCapabilities"]
1013

11-
def __init__(self, data: dict, url: str = None):
12-
super(RESTCapabilities, self).__init__(data)
13-
self.capabilities = data
14-
self.url = url
15-
16-
def get(self, key: str, default=None):
17-
return self.capabilities.get(key, default)
18-
19-
def deep_get(self, *keys, default=None):
20-
return deep_get(self.capabilities, *keys, default=default)
21-
22-
def api_version(self) -> str:
23-
""" Get openEO version."""
24-
if 'api_version' in self.capabilities:
25-
return self.capabilities.get('api_version')
26-
else:
27-
# Legacy/deprecated
28-
return self.capabilities.get('version')
29-
30-
def list_features(self):
31-
""" List all supported features / endpoints."""
32-
return self.capabilities.get('endpoints')
33-
34-
def has_features(self, method_name):
35-
""" Check whether a feature / endpoint is supported."""
36-
# Field: endpoints > ... TODO
37-
pass
38-
39-
def supports_endpoint(self, path: str, method="GET"):
40-
return any(
41-
endpoint.get("path") == path and method.upper() in endpoint.get("methods", [])
42-
for endpoint in self.capabilities.get("endpoints", [])
43-
)
44-
45-
def currency(self) -> Optional[str]:
46-
"""Get default billing currency."""
47-
return self.deep_get("billing", "currency", default=None)
48-
49-
def list_plans(self) -> List[dict]:
50-
"""List all billing plans."""
51-
return self.deep_get("billing", "plans", default=[])
52-
53-
def _repr_html_(self):
54-
return render_component("capabilities", data = self.capabilities, parameters = {"url": self.url})
14+
# Legacy alias
15+
RESTCapabilities = OpenEoCapabilities

tests/rest/test_capabilities.py

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,51 @@
1-
from openeo.rest.rest_capabilities import RESTCapabilities
1+
from openeo.rest.capabilities import OpenEoCapabilities
2+
from openeo.utils.version import ComparableVersion
23

34

4-
class TestCapabilities:
5+
class TestOpenEoCapabilities:
6+
7+
def test_api_version(self):
8+
capabilities = OpenEoCapabilities(
9+
{
10+
"api_version": "1.2.3",
11+
}
12+
)
13+
assert capabilities.api_version() == "1.2.3"
14+
15+
def test_api_version_check(self):
16+
capabilities = OpenEoCapabilities(
17+
{
18+
"api_version": "1.2.3",
19+
}
20+
)
21+
checker = capabilities.api_version_check
22+
assert isinstance(checker, ComparableVersion)
23+
assert checker == "1.2.3"
24+
assert checker > "1.2"
25+
assert checker < "1.5"
26+
27+
def test_supports_endpoint(self):
28+
capabilities = OpenEoCapabilities(
29+
{
30+
"api_version": "1.2.3",
31+
"endpoints": [
32+
{"path": "/collections", "methods": ["GET"]},
33+
{"path": "/jobs", "methods": ["GET", "POST"]},
34+
],
35+
}
36+
)
37+
assert capabilities.supports_endpoint(path="/collections", method="GET")
38+
assert not capabilities.supports_endpoint(path="/collections", method="POST")
39+
assert capabilities.supports_endpoint(path="/jobs", method="GET")
40+
assert capabilities.supports_endpoint(path="/jobs", method="POST")
41+
542
def test_currency(self):
6-
assert RESTCapabilities({}).currency() is None
7-
assert RESTCapabilities({"billing": None}).currency() is None
8-
assert RESTCapabilities({"billing": {"currency": "EUR"}}).currency() == "EUR"
43+
assert OpenEoCapabilities({}).currency() is None
44+
assert OpenEoCapabilities({"billing": None}).currency() is None
45+
assert OpenEoCapabilities({"billing": {"currency": "EUR"}}).currency() == "EUR"
946

1047
def test_list_plans(self):
11-
assert RESTCapabilities({}).list_plans() == []
12-
assert RESTCapabilities({"billing": None}).list_plans() == []
13-
assert RESTCapabilities({"billing": {"plans": []}}).list_plans() == []
14-
assert RESTCapabilities(
15-
{"billing": {"plans": [{"name": "free"}]}}
16-
).list_plans() == [{"name": "free"}]
48+
assert OpenEoCapabilities({}).list_plans() == []
49+
assert OpenEoCapabilities({"billing": None}).list_plans() == []
50+
assert OpenEoCapabilities({"billing": {"plans": []}}).list_plans() == []
51+
assert OpenEoCapabilities({"billing": {"plans": [{"name": "free"}]}}).list_plans() == [{"name": "free"}]

tests/rest/test_connection.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,6 @@ def test_capabilities_api_version(requests_mock):
525525
requests_mock.get(API_URL, status_code=200, json={"api_version": "1.0.0"})
526526
con = openeo.connect("https://oeo.test")
527527
capabilities = con.capabilities()
528-
assert capabilities.version() == "1.0.0"
529528
assert capabilities.api_version() == "1.0.0"
530529

531530

0 commit comments

Comments
 (0)