diff --git a/openeo/rest/connection.py b/openeo/rest/connection.py index 876153618..e4af63c28 100644 --- a/openeo/rest/connection.py +++ b/openeo/rest/connection.py @@ -75,7 +75,7 @@ from openeo.rest.graph_building import CollectionProperty from openeo.rest.job import BatchJob, RESTJob from openeo.rest.mlmodel import MlModel -from openeo.rest.models.general import CollectionListingResponse +from openeo.rest.models.general import CollectionListingResponse, ProcessListingResponse from openeo.rest.service import Service from openeo.rest.udp import Parameter, RESTUserDefinedProcess from openeo.rest.userfile import UserFile @@ -1050,23 +1050,22 @@ def collection_metadata(self, name) -> CollectionMetadata: # TODO: duplication with `Connection.describe_collection`: deprecate one or the other? return CollectionMetadata(metadata=self.describe_collection(name)) - def list_processes(self, namespace: Optional[str] = None) -> List[dict]: - # TODO: Maybe format the result dictionary so that the process_id is the key of the dictionary. + def list_processes(self, namespace: Optional[str] = None) -> ProcessListingResponse: """ Loads all available processes of the back end. :param namespace: The namespace for which to list processes. - :return: processes_dict: Dict All available processes of the back end. + :return: listing of available processes """ + # TODO: Maybe format the result dictionary so that the process_id is the key of the dictionary. if namespace is None: - processes = self._capabilities_cache.get( - key=("processes", "backend"), - load=lambda: self.get('/processes', expected_status=200).json()["processes"] + response = self._capabilities_cache.get( + key=("processes", "backend"), load=lambda: self.get("/processes", expected_status=200).json() ) else: - processes = self.get('/processes/' + namespace, expected_status=200).json()["processes"] - return VisualList("processes", data=processes, parameters={'show-graph': True, 'provide-download': False}) + response = self.get("/processes/" + namespace, expected_status=200).json() + return ProcessListingResponse(data=response) def describe_process(self, id: str, namespace: Optional[str] = None) -> dict: """ diff --git a/openeo/rest/models/general.py b/openeo/rest/models/general.py index ef751e365..1484bc234 100644 --- a/openeo/rest/models/general.py +++ b/openeo/rest/models/general.py @@ -47,10 +47,44 @@ def _repr_html_(self): @property def links(self) -> List[Link]: - """Get links from collections response.""" + """Get links related to this resource.""" return [Link.from_dict(d) for d in self._data.get("links", [])] @property def ext_federation(self) -> FederationExtension: - """Accessor for federation extension data.""" + """Accessor for federation extension data related to this resource.""" + return FederationExtension(self._data) + + +class ProcessListingResponse(list): + """ + Container for process metadata listing received from a ``GET /processes`` request. + + This object mimics a list of process metadata dictionaries, + which was the original return API of :py:meth:`~openeo.rest.connection.Connection.list_processes()`, + but now also includes additional metadata like links and extensions. + + :param data: response data from a ``GET /processes`` request + """ + + __slots__ = ["_data"] + + def __init__(self, data: dict): + self._data = data + # Mimic original list of process metadata dictionaries + super().__init__(data["processes"]) + + def _repr_html_(self): + return render_component( + component="processes", data=self, parameters={"show-graph": True, "provide-download": False} + ) + + @property + def links(self) -> List[Link]: + """Get links related to this resource.""" + return [Link.from_dict(d) for d in self._data.get("links", [])] + + @property + def ext_federation(self) -> FederationExtension: + """Accessor for federation extension data related to this resource.""" return FederationExtension(self._data) diff --git a/tests/rest/test_connection.py b/tests/rest/test_connection.py index c224fbac3..8490a06a7 100644 --- a/tests/rest/test_connection.py +++ b/tests/rest/test_connection.py @@ -3407,6 +3407,23 @@ def test_list_processes_namespace(requests_mock): assert m.call_count == 1 +def test_list_processes_extra_metadata(requests_mock): + requests_mock.get(API_URL, json={"api_version": "1.0.0"}) + m = requests_mock.get( + API_URL + "processes", + json={ + "processes": [{"id": "add"}, {"id": "mask"}], + "links": [{"rel": "next", "href": "https://oeo.test/processes?page=2"}], + "federation:missing": ["oeob"], + }, + ) + conn = Connection(API_URL) + processes = conn.list_processes() + assert processes == [{"id": "add"}, {"id": "mask"}] + assert processes.links == [Link(rel="next", href="https://oeo.test/processes?page=2", type=None, title=None)] + assert processes.ext_federation.missing == ["oeob"] + + def test_get_job(requests_mock): requests_mock.get(API_URL, json={"api_version": "1.0.0"}) conn = Connection(API_URL)