From f364222c10774ec5614fbfd08c68b1cbe1355231 Mon Sep 17 00:00:00 2001 From: Stefaan Lippens Date: Fri, 18 Sep 2020 15:14:07 +0200 Subject: [PATCH 1/2] Issue #10: add `get_process` to get process function by name (as string) --- src/openeo_processes/__init__.py | 3 +- src/openeo_processes/utils.py | 49 ++++++++++++++++++++++++++++++-- tests/test_utils.py | 17 ++++++++++- 3 files changed, 64 insertions(+), 5 deletions(-) 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..63a78fa5 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,46 @@ def fun_wrapper(*args, **kwargs): return cls_fun(*args, **kwargs) + _processes[processor.__name__] = 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..42a8539e 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,18 @@ ]) 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") + + +def test_get_process(): + fun = get_process("add") + assert fun(2, 3) == 5 + fun = get_process("multiply") + assert fun(2, 3) == 6 + fun = get_process("sum") + assert fun([1, 2, 3, 4, 5, 6]) == 21 From 7e0b25c0cd14453ef1aef52a6d45f3811ef9288c Mon Sep 17 00:00:00 2001 From: Stefaan Lippens Date: Tue, 22 Sep 2020 12:47:51 +0200 Subject: [PATCH 2/2] Issue #10: ignore trailing underscore in process function name --- .gitignore | 1 + src/openeo_processes/utils.py | 3 ++- tests/test_utils.py | 24 +++++++++++++++++------- 3 files changed, 20 insertions(+), 8 deletions(-) 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/utils.py b/src/openeo_processes/utils.py index 63a78fa5..1ef38ae8 100644 --- a/src/openeo_processes/utils.py +++ b/src/openeo_processes/utils.py @@ -82,7 +82,8 @@ def fun_wrapper(*args, **kwargs): return cls_fun(*args, **kwargs) - _processes[processor.__name__] = fun_wrapper + process_id = processor.__name__.rstrip('_') + _processes[process_id] = fun_wrapper return fun_wrapper diff --git a/tests/test_utils.py b/tests/test_utils.py index 42a8539e..1b74e2ed 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -32,12 +32,22 @@ 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_") -def test_get_process(): - fun = get_process("add") - assert fun(2, 3) == 5 - fun = get_process("multiply") - assert fun(2, 3) == 6 - fun = get_process("sum") - assert fun([1, 2, 3, 4, 5, 6]) == 21 +@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