-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue #297 Improve compliance with 'remote-udp' extension
- Loading branch information
Showing
7 changed files
with
262 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
__version__ = "0.106.0a1" | ||
__version__ = "0.107.0a1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import logging | ||
import requests | ||
from typing import NamedTuple, List, Optional | ||
from openeo_driver.errors import OpenEOApiException | ||
|
||
_log = logging.getLogger(__name__) | ||
|
||
|
||
class ProcessDefinition(NamedTuple): | ||
""" | ||
Like `UserDefinedProcessMetadata`, but with different defaults | ||
(e.g. process graph and parameters are required). | ||
""" | ||
|
||
# Process id | ||
id: str | ||
# Flat-graph representation of the process | ||
process_graph: dict | ||
# List of parameters expected by the process | ||
parameters: List[dict] | ||
# Definition what the process returns | ||
returns: Optional[dict] = None | ||
|
||
|
||
def get_process_definition_from_url(process_id: str, url: str) -> ProcessDefinition: | ||
""" | ||
Get process definition (process graph, parameters, title, ...) from URL, | ||
which should provide: | ||
- a JSON document with the process definition, compatible with | ||
the `GET /process_graphs/{process_graph_id}` openEO API endpoint. | ||
- a JSON doc with process listing, compatible with | ||
the `GET /process_graphs` openEO API endpoint. | ||
""" | ||
_log.debug(f"Trying to load process definition for {process_id=} from {url=}") | ||
# TODO: send headers, e.g. with custom user agent? | ||
# TODO: add/support caching. Add retrying too? | ||
res = requests.get(url=url) | ||
res.raise_for_status() | ||
doc = res.json() | ||
if not isinstance(doc, dict): | ||
raise ValueError(f"Process definition should be a JSON object, but got {type(doc)}.") | ||
|
||
# TODO: deeper validation (e.g. JSON Schema based)? | ||
if "id" in doc and "process_graph" in doc: | ||
_log.debug(f"Detected single process definition for {process_id=} at {url=}") | ||
spec = doc | ||
if spec["id"] != process_id: | ||
raise OpenEOApiException( | ||
status_code=400, | ||
code="ProcessIdMismatch", | ||
message=f"Mismatch between expected process {process_id!r} and process {spec['id']!r} defined at {url!r}.", | ||
) | ||
elif "processes" in doc and "links" in doc: | ||
_log.debug(f"Searching for {process_id=} at process listing {url=}") | ||
found = [ | ||
p for p in doc["processes"] if isinstance(p, dict) and p.get("id") == process_id and p.get("process_graph") | ||
] | ||
if len(found) != 1: | ||
raise OpenEOApiException( | ||
status_code=400, | ||
code="ProcessNotFound", | ||
message=f"Process {process_id!r} not found in process listing at {url!r}.", | ||
) | ||
spec = found[0] | ||
else: | ||
raise OpenEOApiException( | ||
status_code=400, | ||
code="ProcessNotFound", | ||
message=f"No valid process definition for {process_id!r} found at {url!r}.", | ||
) | ||
|
||
return ProcessDefinition( | ||
id=process_id, | ||
process_graph=spec["process_graph"], | ||
parameters=spec.get("parameters", []), | ||
returns=spec.get("returns"), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
from openeo_driver.errors import OpenEOApiException | ||
from openeo_driver.processgraph import get_process_definition_from_url | ||
|
||
import pytest | ||
|
||
|
||
class TestProcessDefinitionFromUrl: | ||
PROCESS_ADD35 = { | ||
"id": "add35", | ||
"process_graph": {"add": {"process_id": "add", "arguments": {"x": 3, "y": 5}, "result": True}}, | ||
"parameters": [], | ||
"returns": {"schema": {"type": "number"}}, | ||
} | ||
|
||
PROCESS_ADD3PARAM = { | ||
"id": "add3param", | ||
"process_graph": { | ||
"add": {"process_id": "add", "arguments": {"x": 3, "y": {"from_parameter": "delta"}}, "result": True} | ||
}, | ||
"parameters": [ | ||
{"name": "delta", "schema": {"type": "number", "optional": True, "default": 1}}, | ||
], | ||
"returns": {"schema": {"type": "number"}}, | ||
} | ||
|
||
def test_get_process_definition_from_url_single(self, requests_mock): | ||
requests_mock.get("https://share.test/add3param.json", json=self.PROCESS_ADD3PARAM) | ||
|
||
pd = get_process_definition_from_url("add3param", "https://share.test/add3param.json") | ||
assert pd.id == "add3param" | ||
assert pd.process_graph == { | ||
"add": {"process_id": "add", "arguments": {"x": 3, "y": {"from_parameter": "delta"}}, "result": True}, | ||
} | ||
assert pd.parameters == [{"name": "delta", "schema": {"type": "number", "optional": True, "default": 1}}] | ||
assert pd.returns == {"schema": {"type": "number"}} | ||
|
||
def test_get_process_definition_from_url_listing(self, requests_mock): | ||
requests_mock.get( | ||
"https://share.test/processes/", | ||
json={ | ||
"processes": [ | ||
self.PROCESS_ADD35, | ||
self.PROCESS_ADD3PARAM, | ||
], | ||
"links": [], | ||
}, | ||
) | ||
|
||
pd = get_process_definition_from_url("add3param", "https://share.test/processes/") | ||
assert pd.id == "add3param" | ||
assert pd.process_graph == { | ||
"add": {"process_id": "add", "arguments": {"x": 3, "y": {"from_parameter": "delta"}}, "result": True}, | ||
} | ||
assert pd.parameters == [{"name": "delta", "schema": {"type": "number", "optional": True, "default": 1}}] | ||
assert pd.returns == {"schema": {"type": "number"}} |
Oops, something went wrong.