diff --git a/.gitignore b/.gitignore index b355c267..dc4e66c2 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,7 @@ MANIFEST # Per-project virtualenvs .venv*/ +venv*/ # folder including testing scripts .scripts diff --git a/src/openeo_processes/__init__.py b/src/openeo_processes/__init__.py index aa03758f..cd327565 100644 --- a/src/openeo_processes/__init__.py +++ b/src/openeo_processes/__init__.py @@ -12,4 +12,5 @@ from openeo_processes.arrays import * from openeo_processes.comparison import * from openeo_processes.math import * -from openeo_processes.texts import * \ No newline at end of file +from openeo_processes.texts import * +from openeo_processes.utils import get_process, has_process diff --git a/src/openeo_processes/utils.py b/src/openeo_processes/utils.py index 5828c55e..1ef38ae8 100644 --- a/src/openeo_processes/utils.py +++ b/src/openeo_processes/utils.py @@ -1,8 +1,9 @@ +import functools import re +from datetime import timezone, timedelta, datetime +from typing import Callable + import numpy as np -from datetime import timezone -from datetime import timedelta -from datetime import datetime def eval_datatype(data): @@ -37,6 +38,10 @@ def eval_datatype(data): return package + '.' + type(data).__name__ +# Registry of processes (dict mapping process id to wrapped process implementation). +_processes = {} + + def process(processor): """ This function serves as a decorator for empty openEO process definitions, which call a class `processor` defining @@ -53,6 +58,7 @@ def process(processor): Process/function wrapper returning the result of the process. """ + @functools.wraps(processor) def fun_wrapper(*args, **kwargs): cls = processor() @@ -76,9 +82,47 @@ def fun_wrapper(*args, **kwargs): return cls_fun(*args, **kwargs) + process_id = processor.__name__.rstrip('_') + _processes[process_id] = fun_wrapper + return fun_wrapper +def has_process(process_id: str) -> bool: + """ + Check if the given process is defined + + Parameters + ---------- + process_id : str + Process id + + Returns + ------- + True if the process is defined, False otherwise + """ + return process_id in _processes + + +def get_process(process_id: str) -> Callable: + """ + Get the function corresponding with given process id + + Parameters + ---------- + process_id : str + Process id + + Returns + ------- + Python function (callable) that wraps the process + """ + return _processes[process_id] + + + + + def list2nparray(x): """ Converts a list in a nump diff --git a/tests/test_utils.py b/tests/test_utils.py index 5e4b022d..1b74e2ed 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -4,7 +4,7 @@ import numpy as np import pytest import xarray -from openeo_processes.utils import eval_datatype +from openeo_processes.utils import eval_datatype, get_process, has_process @pytest.mark.parametrize(["data", "expected"], [ @@ -26,3 +26,28 @@ ]) def test_eval_datatype(data, expected): assert eval_datatype(data) == expected + + +def test_has_process(): + assert has_process("add") + assert has_process("multiply") + assert not has_process("foobar") + assert has_process("and") + assert not has_process("and_") + assert has_process("or") + assert not has_process("or_") + assert has_process("if") + assert not has_process("if_") + + +@pytest.mark.parametrize(["pid", "args", "expected"], [ + ("add", (2, 3), 5), + ("multiply", (2, 3), 6), + ("sum", ([1, 2, 3, 4, 5, 6],), 21), + ("median", ([2, 5, 3, 8, 11],), 5), + ("and", (False, True), False), + ("or", (False, True), True), +]) +def test_get_process(pid, args, expected): + fun = get_process(pid) + assert fun(*args) == expected