diff --git a/core/base_pattern.py b/core/base_pattern.py index 9277605..a93c8dc 100644 --- a/core/base_pattern.py +++ b/core/base_pattern.py @@ -27,7 +27,7 @@ class BasePattern: outputs:Dict[str,Any] # A collection of variables to be swept over for job scheduling sweep:Dict[str,Any] - + # TODO Add requirements to patterns def __init__(self, name:str, recipe:str, parameters:Dict[str,Any]={}, outputs:Dict[str,Any]={}, sweep:Dict[str,Any]={}): """BasePattern Constructor. This will check that any class inheriting diff --git a/functionality/requirements.py b/functionality/requirements.py new file mode 100644 index 0000000..ce45521 --- /dev/null +++ b/functionality/requirements.py @@ -0,0 +1,43 @@ +""" +This file contains functions and definitions used in pattern and recipe +requirements, and assessed by handlers and conductors. + +Author(s): David Marchant +""" + +from typing import Any, Dict, List, Tuple, Union + +from core.correctness.validation import check_type + +REQUIREMENT_PYTHON = "python" +REQ_PYTHON_MODULES = "modules" +REQ_PYTHON_VERSION = "version" +REQ_PYTHON_ENVIRONMENT = "environment" + + +def create_requirement_dict(key:str, entires:Dict[str,Any] + )->Tuple[str,Dict[str,Any]]: + return key, entires + +def create_python_requirements(modules:Union[str,List[str]]="", + version:str="", environment:str="")->Dict[str,Any]: + check_type(modules, str, alt_types=[List]) + if not isinstance(modules, List): + modules = [modules] + for i, module in enumerate(modules): + check_type(module, str, hint="create_python_requirement.modules[i]") + check_type(version, str) + check_type(environment, str) + + python_reqs = {} + + if modules != [""]: + python_reqs[REQ_PYTHON_MODULES] = modules + + if version: + python_reqs[REQ_PYTHON_VERSION] = version + + if environment: + python_reqs[REQ_PYTHON_ENVIRONMENT] = environment + + return create_requirement_dict(REQUIREMENT_PYTHON, python_reqs) diff --git a/tests/test_functionality.py b/tests/test_functionality.py index f7a44e4..d971cd1 100644 --- a/tests/test_functionality.py +++ b/tests/test_functionality.py @@ -13,7 +13,7 @@ from core.base_rule import BaseRule from core.correctness.vars import CHAR_LOWERCASE, CHAR_UPPERCASE, \ SHA256, EVENT_TYPE, EVENT_PATH, EVENT_TYPE_WATCHDOG, \ WATCHDOG_BASE, WATCHDOG_HASH, EVENT_RULE, JOB_PARAMETERS, JOB_HASH, \ - PYTHON_FUNC, JOB_ID, JOB_EVENT, SWEEP_JUMP, SWEEP_START, SWEEP_STOP, \ + PYTHON_FUNC, JOB_ID, JOB_EVENT, \ JOB_TYPE, JOB_PATTERN, JOB_RECIPE, JOB_RULE, JOB_STATUS, JOB_CREATE_TIME, \ JOB_REQUIREMENTS, STATUS_QUEUED, JOB_TYPE_PAPERMILL from functionality.debug import setup_debugging @@ -31,6 +31,9 @@ from functionality.naming import _generate_id from functionality.parameterisation import parameterize_jupyter_notebook, \ parameterize_python_script from functionality.process_io import wait +from functionality.requirements import create_python_requirements, \ + REQUIREMENT_PYTHON, REQ_PYTHON_ENVIRONMENT, REQ_PYTHON_MODULES, \ + REQ_PYTHON_VERSION from patterns import FileEventPattern from recipes import JupyterNotebookRecipe from shared import setup, teardown, valid_recipe_two, valid_recipe_one, \ @@ -886,3 +889,87 @@ class ProcessIoTests(unittest.TestCase): elif readable == pipe_one_reader: msg = readable.recv() self.assertEqual(msg, 1) + +class RequirementsTest(unittest.TestCase): + def setUp(self)->None: + super().setUp() + setup() + + def tearDown(self)->None: + super().tearDown() + teardown() + + # Test Python requirement testings + def testPythonRequirementCreation(self)->None: + key, reqs = create_python_requirements() + + self.assertIsInstance(key, str) + self.assertEqual(key, REQUIREMENT_PYTHON) + self.assertIsInstance(reqs, dict) + self.assertEqual(reqs, {}) + + key, reqs = create_python_requirements(modules="first") + + self.assertIsInstance(key, str) + self.assertEqual(key, REQUIREMENT_PYTHON) + self.assertIsInstance(reqs, dict) + self.assertEqual(len(reqs), 1) + self.assertIn(REQ_PYTHON_MODULES, reqs) + self.assertEqual(len(reqs[REQ_PYTHON_MODULES]), 1) + self.assertIsInstance(reqs[REQ_PYTHON_MODULES], list) + self.assertEqual(reqs[REQ_PYTHON_MODULES], ["first"]) + + key, reqs = create_python_requirements(modules=["first", "second"]) + + self.assertIsInstance(key, str) + self.assertEqual(key, REQUIREMENT_PYTHON) + self.assertIsInstance(reqs, dict) + self.assertEqual(len(reqs), 1) + self.assertIn(REQ_PYTHON_MODULES, reqs) + self.assertEqual(len(reqs[REQ_PYTHON_MODULES]), 2) + self.assertIsInstance(reqs[REQ_PYTHON_MODULES], list) + self.assertEqual(reqs[REQ_PYTHON_MODULES], ["first", "second"]) + + key, reqs = create_python_requirements(version="3.10.6") + + self.assertIsInstance(key, str) + self.assertEqual(key, REQUIREMENT_PYTHON) + self.assertIsInstance(reqs, dict) + self.assertEqual(len(reqs), 1) + self.assertIn(REQ_PYTHON_VERSION, reqs) + self.assertIsInstance(reqs[REQ_PYTHON_VERSION], str) + self.assertEqual(reqs[REQ_PYTHON_VERSION], "3.10.6") + + key, reqs = create_python_requirements(environment="env") + + self.assertIsInstance(key, str) + self.assertEqual(key, REQUIREMENT_PYTHON) + self.assertIsInstance(reqs, dict) + self.assertEqual(len(reqs), 1) + self.assertIn(REQ_PYTHON_ENVIRONMENT, reqs) + self.assertIsInstance(reqs[REQ_PYTHON_ENVIRONMENT], str) + self.assertEqual(reqs[REQ_PYTHON_ENVIRONMENT], "env") + + key, reqs = create_python_requirements( + modules=["first", "second"], + version="3.10.6", + environment="env" + ) + + self.assertIsInstance(key, str) + self.assertEqual(key, REQUIREMENT_PYTHON) + self.assertIsInstance(reqs, dict) + self.assertEqual(len(reqs), 3) + self.assertIn(REQ_PYTHON_MODULES, reqs) + self.assertEqual(len(reqs[REQ_PYTHON_MODULES]), 2) + self.assertIsInstance(reqs[REQ_PYTHON_MODULES], list) + self.assertEqual(reqs[REQ_PYTHON_MODULES], ["first", "second"]) + self.assertIn(REQ_PYTHON_VERSION, reqs) + self.assertIsInstance(reqs[REQ_PYTHON_VERSION], str) + self.assertEqual(reqs[REQ_PYTHON_VERSION], "3.10.6") + self.assertIn(REQ_PYTHON_ENVIRONMENT, reqs) + self.assertIsInstance(reqs[REQ_PYTHON_ENVIRONMENT], str) + self.assertEqual(reqs[REQ_PYTHON_ENVIRONMENT], "env") + + # TODO expand me and add values for other attributes + \ No newline at end of file diff --git a/tests/test_recipes.py b/tests/test_recipes.py index 06f2257..e854a9e 100644 --- a/tests/test_recipes.py +++ b/tests/test_recipes.py @@ -831,5 +831,4 @@ class PythonTests(unittest.TestCase): }) self.assertTrue(status) - # TODO test default parameter function execution \ No newline at end of file