From ef8678c7a6d6fa56c69e48ad90887847633c933f Mon Sep 17 00:00:00 2001 From: Bernhard Mallinger Date: Wed, 17 Jan 2024 13:36:45 +0100 Subject: [PATCH] Use new client facing error class --- pygeoapi_kubernetes_papermill/notebook.py | 17 ++++++++++++----- tests/test_notebook_processor.py | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/pygeoapi_kubernetes_papermill/notebook.py b/pygeoapi_kubernetes_papermill/notebook.py index 609dd83..8f70f85 100644 --- a/pygeoapi_kubernetes_papermill/notebook.py +++ b/pygeoapi_kubernetes_papermill/notebook.py @@ -31,6 +31,7 @@ from dataclasses import dataclass, field from datetime import datetime, date import functools +from http import HTTPStatus import json import logging import mimetypes @@ -97,6 +98,10 @@ } +class ProcessorClientError(ProcessorExecuteError): + http_status_code = HTTPStatus.BAD_REQUEST + + CONTAINER_HOME = Path("/home/jovyan") JOVIAN_UID = 1000 JOVIAN_GID = 100 @@ -226,14 +231,16 @@ def create_job_pod_spec( try: requested = RequestParameters.from_dict(data) except (TypeError, KeyError) as e: - raise ProcessorExecuteError(str(e)) from e + raise ProcessorClientError(user_msg=f"Invalid parameter: {e}") from e image = self._image(requested.image) output_notebook = self.setup_output(requested, job_id_from_job_name(job_name)) if requested.run_on_fargate and not self.allow_fargate: - raise RuntimeError("run_on_fargate is not allowed on this pygeoapi") + raise ProcessorClientError( + user_msg="run_on_fargate is not allowed on this pygeoapi" + ) extra_podspec: Dict[str, Any] = { "tolerations": [ @@ -438,7 +445,7 @@ def _image(self, requested_image: Optional[str]) -> str: if self.allowed_images_regex: if not re.fullmatch(self.allowed_images_regex, image): msg = f"Image {image} is not allowed, only {self.allowed_images_regex}" - raise RuntimeError(msg) + raise ProcessorClientError(user_msg=msg) return image @@ -465,8 +472,8 @@ def affinity(self, requested_node_purpose: Optional[str]) -> k8s_client.V1Affini if not re.fullmatch( self.allowed_node_purposes_regex, requested_node_purpose ): - raise RuntimeError( - f"Node purpose {requested_node_purpose} not allowed, " + raise ProcessorClientError( + user_msg=f"Node purpose {requested_node_purpose} not allowed, " f"only {self.allowed_node_purposes_regex}" ) else: diff --git a/tests/test_notebook_processor.py b/tests/test_notebook_processor.py index b02f827..c04fc69 100644 --- a/tests/test_notebook_processor.py +++ b/tests/test_notebook_processor.py @@ -45,6 +45,7 @@ from pygeoapi_kubernetes_papermill.notebook import ( CONTAINER_HOME, PapermillNotebookKubernetesProcessor, + ProcessorClientError, notebook_job_output, ) @@ -509,7 +510,7 @@ def test_allowed_custom_image_can_be_passed(create_pod_kwargs_with): def test_not_allowed_custom_image_is_rejected(create_pod_kwargs_with): image = "euroevil:2.0" processor = _create_processor({"allowed_images_regex": "euro.*:1\\.*"}) - with pytest.raises(RuntimeError): + with pytest.raises(ProcessorClientError): processor.create_job_pod_spec(**create_pod_kwargs_with({"image": image})) @@ -534,7 +535,7 @@ def test_node_selector_can_be_overwritten(create_pod_kwargs_with, papermill_proc def test_node_selector_restriced_by_regex(create_pod_kwargs_with, papermill_processor): node_purpose = "disallowed-node" - with pytest.raises(RuntimeError): + with pytest.raises(ProcessorClientError): papermill_processor.create_job_pod_spec( **create_pod_kwargs_with({"node_purpose": node_purpose}) ) @@ -629,3 +630,12 @@ def test_extra_requirements_are_added(create_pod_kwargs): resources = job_pod_spec.pod_spec.containers[0].resources assert resources.requests["ice/cream"] == 1 assert resources.limits["ice/cream"] == 3 + + +def test_invalid_params_raises_user_error(papermill_processor, create_pod_kwargs_with): + with pytest.raises(ProcessorClientError) as exc_info: + papermill_processor.create_job_pod_spec( + # NOTE: this is wrong because mem limit is str + **create_pod_kwargs_with({"mem_limit": 4}) + ) + assert 'mem_limit' in exc_info.value.message