Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue #693 add search for schema and find parameters from the backend #698

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

ElienVandermaesenVITO
Copy link
Contributor

Copy link
Member

@soxofaan soxofaan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this PR you add a lot of utility functions. A couple of notes on that:

  • they are al public at the moment, so adding them adds the burden to keep/maintain/support them. In that sense, they should also get good test coverage.
  • some of the seem quite tailored for the specific use case of this PR, while they are named very generically

also note that we already have parsing functionality for process definitions: e.g. see starting point openeo.internal.processes.Process.from_dict(). I think that should eliminate the need for all these new utility functions

I think it's also important that the core goal of this PR gets unit tests coverage

openeo/rest/connection.py Outdated Show resolved Hide resolved
openeo/rest/connection.py Outdated Show resolved Hide resolved
openeo/rest/connection.py Outdated Show resolved Hide resolved
openeo/rest/datacube.py Outdated Show resolved Hide resolved
@ElienVandermaesenVITO
Copy link
Contributor Author

The test fail because of No mock address: GET https://oeo.test/processes. Do I have to change the test and add the address or is there another way to solve it?

@soxofaan
Copy link
Member

soxofaan commented Jan 9, 2025

this feature indeed impacts existing tests

FAILED tests/rest/datacube/test_datacube100.py::test_sar_backscatter_defaults - requests_mock.exceptions.NoMockAddress: No mock address: GET https://oeo.test/processes
FAILED tests/rest/datacube/test_datacube100.py::test_sar_backscatter_custom - requests_mock.exceptions.NoMockAddress: No mock address: GET https://oeo.test/processes
FAILED tests/rest/datacube/test_datacube100.py::test_sar_backscatter_coefficient_none - requests_mock.exceptions.NoMockAddress: No mock address: GET https://oeo.test/processes
FAILED tests/rest/datacube/test_datacube100.py::test_sar_backscatter_coefficient_invalid - requests_mock.exceptions.NoMockAddress: No mock address: GET https://oeo.test/processes

doing cube.sar_backscatter() now triggers a GET /processes request, so you should indeed add a mock for that in these tests

@@ -687,3 +687,22 @@ def normalize_crs(crs: Any, *, use_pyproj: bool = True) -> Union[None, int, str]
raise ValueError(f"Can not normalize CRS data {type(crs)}")

return crs


def search_list_for_dict_key(lst: list, key: str) -> Union[dict, list]:
Copy link
Contributor Author

@ElienVandermaesenVITO ElienVandermaesenVITO Jan 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved this function to util.py, because it couldn't be imported from connection.py due to a circular import issue. Can it stay here or should it be moved elsewhere @soxofaan

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of this generic utility, I would define a method get_enum_options() on the Schema object

Copy link
Member

@soxofaan soxofaan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some quick notes

openeo/rest/connection.py Outdated Show resolved Hide resolved
openeo/rest/connection.py Outdated Show resolved Hide resolved
openeo/rest/connection.py Outdated Show resolved Hide resolved
openeo/rest/connection.py Outdated Show resolved Hide resolved
openeo/rest/datacube.py Outdated Show resolved Hide resolved
…ore compact, and remove get_schema_from_process_parameter
@@ -127,6 +127,12 @@ def from_json_file(cls, path: Union[str, Path]) -> Process:
with Path(path).open("r") as f:
return cls.from_json(f.read())

def get_parameter(self, parameter_id: str) -> Union[dict, list]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a test for this new method?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also to stay closer to the openEO spec, I would just use name as argument here. "Parameter Id" is not really a thing in the spec

@@ -38,6 +38,7 @@
from openeo.internal.graph_building import FlatGraphableMixin, PGNode, as_flat_graph
from openeo.internal.jupyter import VisualDict, VisualList
from openeo.internal.processes.builder import ProcessBuilderBase
from openeo.internal.processes.parse import Process
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this adds an unused import I think

schema = Process.from_dict(self.connection.describe_process("sar_backscatter")).get_parameter("coefficient")
coefficient_options = search_list_for_dict_key(schema, "enum") + [None]
except Exception:
log.warning(f"Failed to extract option for coefficient in sar_backscatter")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
log.warning(f"Failed to extract option for coefficient in sar_backscatter")
log.warning(f"Failed to extract coefficient options for process `sar_backscatter`: {e}")

for parameter in self.parameters:
if parameter.name == parameter_id:
return parameter.schema.schema
raise LookupError(f"Expected parameter {parameter_id} not found.")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
raise LookupError(f"Expected parameter {parameter_id} not found.")
raise LookupError(f"Parameter {parameter_id!r} not found.")

try:
schema = Process.from_dict(self.connection.describe_process("sar_backscatter")).get_parameter("coefficient")
coefficient_options = search_list_for_dict_key(schema, "enum") + [None]
except Exception:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
except Exception:
except Exception as e:

def get_parameter(self, parameter_id: str) -> Union[dict, list]:
for parameter in self.parameters:
if parameter.name == parameter_id:
return parameter.schema.schema
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would return the whole parameter instead of just its schema to be more generic

Suggested change
return parameter.schema.schema
return parameter

@@ -687,3 +687,22 @@ def normalize_crs(crs: Any, *, use_pyproj: bool = True) -> Union[None, int, str]
raise ValueError(f"Can not normalize CRS data {type(crs)}")

return crs


def search_list_for_dict_key(lst: list, key: str) -> Union[dict, list]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of this generic utility, I would define a method get_enum_options() on the Schema object

"returns": {"description": "incremented value", "schema": {"type": "integer"}},
}
]
requests_mock.get(API_URL + "/processes", json={"processes": processes})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not add these request_mock to the existing tests, because these tests have to keep working without change.

Instead, I would add new tests where a custom sar_backscatter is mocked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants