Skip to content

Commit a52a5b8

Browse files
committed
EP-3609 add listing public user defined processes (POC)
POC: API not fully specified yet, see Open-EO/openeo-api#310
1 parent 978e48c commit a52a5b8

File tree

3 files changed

+82
-51
lines changed

3 files changed

+82
-51
lines changed

openeo_driver/dummy/dummy_backend.py

+6-11
Original file line numberDiff line numberDiff line change
@@ -344,17 +344,12 @@ def delete_job(self, job_id: str, user_id: str):
344344

345345

346346
class DummyUserDefinedProcesses(UserDefinedProcesses):
347-
_processes: Dict[Tuple[str, str], UserDefinedProcessMetadata] = {
348-
('Mr.Test', 'udp1'): UserDefinedProcessMetadata(
349-
id='udp1',
350-
process_graph={'process1': {}},
351-
public=True
352-
),
353-
('Mr.Test', 'udp2'): UserDefinedProcessMetadata(
354-
id='udp2',
355-
process_graph={'process1': {}}
356-
)
357-
}
347+
def __init__(self):
348+
super().__init__()
349+
self._processes: Dict[Tuple[str, str], UserDefinedProcessMetadata] = {}
350+
351+
def reset(self, db: Dict[Tuple[str, str], UserDefinedProcessMetadata]):
352+
self._processes = db
358353

359354
def get(self, user_id: str, process_id: str) -> Union[UserDefinedProcessMetadata, None]:
360355
return self._processes.get((user_id, process_id))

openeo_driver/views.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -972,10 +972,19 @@ def processes():
972972

973973

974974
@api_endpoint
975-
@openeo_bp.route('/processes/<process_id>', methods=['GET'])
976-
def process(process_id):
977-
spec = get_process_registry(requested_api_version()).get_spec(name=process_id)
978-
return jsonify(spec)
975+
@openeo_bp.route('/processes/<namespace>', methods=['GET'])
976+
def process(namespace):
977+
# TODO: convention for namespaces (user, organisation, ....) see https://github.com/Open-EO/openeo-api/issues/310
978+
if namespace == "backend":
979+
processes = get_process_registry(requested_api_version()).get_specs()
980+
elif namespace.startswith("u:"):
981+
user_id = namespace.partition("u:")[-1]
982+
user_udps = [p for p in backend_implementation.user_defined_processes.get_for_user(user_id) if p.public]
983+
processes = [_jsonable_udp_metadata(udp, full=False) for udp in user_udps]
984+
else:
985+
raise OpenEOApiException("Could not handle namespace {n!r}".format(n=namespace))
986+
# TODO: pagination links?
987+
return jsonify({'processes': processes, 'links': []})
979988

980989

981990
@api_endpoint(hidden=True)

tests/test_views.py

+63-36
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
import pytest
1212

1313
from openeo.capabilities import ComparableVersion
14-
from openeo_driver.backend import BatchJobMetadata
14+
from openeo_driver.backend import BatchJobMetadata, UserDefinedProcessMetadata
1515
from openeo_driver.dummy import dummy_backend
1616
import openeo_driver.testing
1717
from openeo_driver.testing import TEST_USER, ApiResponse, TEST_USER_AUTH_HEADER
18-
from openeo_driver.views import app, EndpointRegistry, build_backend_deploy_metadata, _normalize_collection_metadata
18+
from openeo_driver.views import app, EndpointRegistry, build_backend_deploy_metadata, _normalize_collection_metadata, \
19+
backend_implementation
1920
from .data import TEST_DATA_ROOT
2021
from .test_users import _build_basic_http_auth_header
2122

@@ -112,7 +113,6 @@ def test_capabilities_endpoints(self, api100):
112113
assert endpoints["/result"] == ["POST"]
113114
assert endpoints["/jobs"] == ["GET", "POST"]
114115
assert endpoints["/processes"] == ["GET"]
115-
assert endpoints["/processes/{process_id}"] == ["GET"]
116116
assert endpoints["/udf_runtimes"] == ["GET"]
117117
assert endpoints["/file_formats"] == ["GET"]
118118
assert endpoints["/service_types"] == ["GET"]
@@ -232,8 +232,12 @@ def test_file_formats(self, api100):
232232
}
233233
}
234234

235-
def test_processes(self, api):
236-
resp = api.get('/processes').assert_status_code(200).json
235+
@pytest.mark.parametrize("endpoint", [
236+
"/processes",
237+
"/processes/backend"
238+
])
239+
def test_processes(self, api, endpoint):
240+
resp = api.get(endpoint).assert_status_code(200).json
237241
processes = resp["processes"]
238242
process_ids = set(p['id'] for p in processes)
239243
assert {"load_collection", "min", "max", "sin", "merge_cubes", "mask"}.issubset(process_ids)
@@ -267,25 +271,6 @@ def test_processes_non_standard_histogram(self, api):
267271
'schema': {'type': 'object'}
268272
}
269273

270-
def test_process_details(self, api):
271-
spec = api.get('/processes/sin').assert_status_code(200).json
272-
assert spec['id'] == 'sin'
273-
assert "Computes the sine" in spec['description']
274-
if api.api_version_compare.at_least("1.0.0"):
275-
assert spec["parameters"] == [
276-
{'name': 'x', 'description': 'An angle in radians.', 'schema': {'type': ['number', 'null']}}
277-
]
278-
else:
279-
assert spec["parameters"] == {
280-
'x': {
281-
'description': 'An angle in radians.', 'required': True, 'schema': {'type': ['number', 'null']}
282-
}
283-
}
284-
assert spec["returns"]["schema"] == {'type': ['number', 'null']}
285-
286-
def test_process_details_invalid(self, api):
287-
api.get('/processes/blergh').assert_error(400, 'ProcessUnsupported')
288-
289274
def test_processes_040_vs_100(self, api040, api100):
290275
pids040 = {p['id'] for p in api040.get("/processes").assert_status_code(200).json["processes"]}
291276
pids100 = {p['id'] for p in api100.get("/processes").assert_status_code(200).json["processes"]}
@@ -1028,8 +1013,27 @@ def foo_post():
10281013
assert methods == ({"GET"}, {"POST"})
10291014

10301015

1016+
@pytest.fixture
1017+
def udp_store() -> dummy_backend.DummyUserDefinedProcesses:
1018+
udps = backend_implementation.user_defined_processes
1019+
assert isinstance(udps, dummy_backend.DummyUserDefinedProcesses)
1020+
udps.reset({
1021+
('Mr.Test', 'udp1'): UserDefinedProcessMetadata(
1022+
id='udp1',
1023+
process_graph={'process1': {}},
1024+
public=True,
1025+
),
1026+
('Mr.Test', 'udp2'): UserDefinedProcessMetadata(
1027+
id='udp2',
1028+
process_graph={'process1': {}},
1029+
public=False,
1030+
)
1031+
})
1032+
return udps
1033+
1034+
10311035
class TestUserDefinedProcesses:
1032-
def test_add_udp(self, api100):
1036+
def test_add_udp(self, api100, udp_store):
10331037
api100.put('/process_graphs/evi', headers=TEST_USER_AUTH_HEADER, json={
10341038
'id': 'evi',
10351039
'parameters': [
@@ -1041,13 +1045,13 @@ def test_add_udp(self, api100):
10411045
'public': True
10421046
}).assert_status_code(200)
10431047

1044-
new_udp = dummy_backend.DummyUserDefinedProcesses._processes['Mr.Test', 'evi']
1048+
new_udp = udp_store._processes['Mr.Test', 'evi']
10451049
assert new_udp.id == 'evi'
10461050
assert new_udp.parameters == [{'name': 'red'}]
10471051
assert new_udp.process_graph == {'sub': {}}
10481052
assert new_udp.public
10491053

1050-
def test_update_udp(self, api100):
1054+
def test_update_udp(self, api100, udp_store):
10511055
api100.put('/process_graphs/udp1', headers=TEST_USER_AUTH_HEADER, json={
10521056
'id': 'udp1',
10531057
'parameters': [
@@ -1059,13 +1063,13 @@ def test_update_udp(self, api100):
10591063
'public': True
10601064
}).assert_status_code(200)
10611065

1062-
modified_udp = dummy_backend.DummyUserDefinedProcesses._processes['Mr.Test', 'udp1']
1066+
modified_udp = udp_store._processes['Mr.Test', 'udp1']
10631067
assert modified_udp.id == 'udp1'
10641068
assert modified_udp.process_graph == {'add': {}}
10651069
assert modified_udp.parameters == [{'name': 'blue'}]
10661070
assert modified_udp.public
10671071

1068-
def test_list_udps(self, api100):
1072+
def test_list_udps(self, api100, udp_store):
10691073
resp = api100.get('/process_graphs', headers=TEST_USER_AUTH_HEADER).assert_status_code(200)
10701074

10711075
udps = resp.json['processes']
@@ -1074,27 +1078,50 @@ def test_list_udps(self, api100):
10741078
assert 'process_graph' not in udp1
10751079
assert udp1['public']
10761080

1077-
def test_get_udp(self, api100):
1081+
def test_get_udp(self, api100, udp_store):
10781082
resp = api100.get('/process_graphs/udp1', headers=TEST_USER_AUTH_HEADER).assert_status_code(200)
10791083

10801084
udp = resp.json
10811085
assert udp['id'] == 'udp1'
10821086
assert udp['public']
10831087

1084-
def test_get_unknown_udp(self, api100):
1088+
def test_get_unknown_udp(self, api100, udp_store):
10851089
api100.get('/process_graphs/unknown', headers=TEST_USER_AUTH_HEADER).assert_status_code(404)
10861090

1087-
def test_delete_udp(self, api100):
1088-
assert ('Mr.Test', 'udp2') in dummy_backend.DummyUserDefinedProcesses._processes
1091+
def test_delete_udp(self, api100, udp_store):
1092+
assert ('Mr.Test', 'udp2') in udp_store._processes
10891093

10901094
api100.delete('/process_graphs/udp2', headers=TEST_USER_AUTH_HEADER).assert_status_code(204)
10911095

1092-
assert ('Mr.Test', 'udp1') in dummy_backend.DummyUserDefinedProcesses._processes
1093-
assert ('Mr.Test', 'udp2') not in dummy_backend.DummyUserDefinedProcesses._processes
1096+
assert ('Mr.Test', 'udp1') in udp_store._processes
1097+
assert ('Mr.Test', 'udp2') not in udp_store._processes
10941098

1095-
def test_delete_unknown_udp(self, api100):
1099+
def test_delete_unknown_udp(self, api100, udp_store):
10961100
api100.delete('/process_graphs/unknown', headers=TEST_USER_AUTH_HEADER).assert_status_code(404)
10971101

1102+
def test_public_udp(self, api100, udp_store):
1103+
api100.put('/process_graphs/evi', headers=TEST_USER_AUTH_HEADER, json={
1104+
'id': 'evi',
1105+
'parameters': [{'name': 'red'}],
1106+
'process_graph': {'sub': {}},
1107+
'public': True
1108+
}).assert_status_code(200)
1109+
api100.put('/process_graphs/secret', headers=TEST_USER_AUTH_HEADER, json={
1110+
'id': 'secret',
1111+
'parameters': [{'name': 'red'}],
1112+
'process_graph': {'sub': {}},
1113+
'public': False
1114+
}).assert_status_code(200)
1115+
1116+
r = api100.get("/processes/u:Mr.Test").assert_status_code(200)
1117+
assert r.json == {
1118+
"processes": [
1119+
{"id": "udp1", "public": True},
1120+
{"id": "evi", "parameters": [{"name": "red"}], "public": True}
1121+
],
1122+
"links": [],
1123+
}
1124+
10981125

10991126
def test_debug_echo_get(api):
11001127
res = api.get("/_debug/echo?xev=lol", headers={"foo": "bar"}).assert_status_code(200).json

0 commit comments

Comments
 (0)