Skip to content

Commit 6cc64cb

Browse files
committed
Relax runtime validation in UDF._guess_runtime
and improve type annotations along the way related to #470 and Open-EO/openeo-api#510
1 parent ba27981 commit 6cc64cb

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

openeo/rest/_datacube.py

+14-12
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def __init__(
167167
def __repr__(self):
168168
return f"<{type(self).__name__} runtime={self._runtime!r} code={str_truncate(self.code, width=200)!r}>"
169169

170-
def get_runtime(self, connection: Connection) -> str:
170+
def get_runtime(self, connection: Optional[Connection] = None) -> str:
171171
return self._runtime or self._guess_runtime(connection=connection)
172172

173173
@classmethod
@@ -221,7 +221,7 @@ def from_url(
221221
code=code, runtime=runtime, version=version, context=context, _source=url
222222
)
223223

224-
def _guess_runtime(self, connection: Connection) -> str:
224+
def _guess_runtime(self, connection: Optional[Connection] = None) -> str:
225225
"""Guess UDF runtime from UDF source (path) or source code."""
226226
# First, guess UDF language
227227
language = None
@@ -240,22 +240,22 @@ def _guess_runtime(self, connection: Connection) -> str:
240240
# TODO: detection heuristics for R and other languages?
241241
if not language:
242242
raise OpenEoClientException("Failed to detect language of UDF code.")
243-
# Find runtime for language
244-
runtimes = {k.lower(): k for k in connection.list_udf_runtimes().keys()}
245-
if language.lower() in runtimes:
246-
return runtimes[language.lower()]
247-
else:
248-
raise OpenEoClientException(
249-
f"Failed to match UDF language {language!r} with a runtime ({runtimes})"
250-
)
243+
runtime = language
244+
if connection:
245+
# Some additional best-effort validation/normalization of the runtime
246+
# TODO: this just does some case-normalization, just drop that all together to eliminate
247+
# the dependency on a connection object. See https://github.com/Open-EO/openeo-api/issues/510
248+
runtimes = {k.lower(): k for k in connection.list_udf_runtimes().keys()}
249+
runtime = runtimes.get(runtime.lower(), runtime)
250+
return runtime
251251

252252
def _guess_runtime_from_suffix(self, suffix: str) -> Union[str]:
253253
return {
254254
".py": "Python",
255255
".r": "R",
256256
}.get(suffix.lower())
257257

258-
def get_run_udf_callback(self, connection: Connection, data_parameter: str = "data") -> PGNode:
258+
def get_run_udf_callback(self, connection: Optional[Connection] = None, data_parameter: str = "data") -> PGNode:
259259
"""
260260
For internal use: construct `run_udf` node to be used as callback in `apply`, `reduce_dimension`, ...
261261
"""
@@ -272,18 +272,20 @@ def get_run_udf_callback(self, connection: Connection, data_parameter: str = "da
272272
def build_child_callback(
273273
process: Union[str, PGNode, typing.Callable, UDF],
274274
parent_parameters: List[str],
275-
connection: Optional["openeo.Connection"] = None,
275+
connection: Optional[Connection] = None,
276276
) -> dict:
277277
"""
278278
Build a "callback" process: a user defined process that is used by another process (such
279279
as `apply`, `apply_dimension`, `reduce`, ....)
280280
281281
:param process: process id string, PGNode or callable that uses the ProcessBuilder mechanism to build a process
282282
:param parent_parameters: list of parameter names defined for child process
283+
:param connection: optional connection object to improve runtime validation for UDFs
283284
:return:
284285
"""
285286
# TODO: move this to more generic process graph building utility module
286287
# TODO: autodetect the parameters defined by parent process?
288+
# TODO: eliminate need for connection object (also see `UDF._guess_runtime`)
287289
if isinstance(process, PGNode):
288290
# Assume this is already a valid callback process
289291
pg = process

0 commit comments

Comments
 (0)