rewored rules to only invoke base rule, and added bash jobs

This commit is contained in:
PatchOfScotland
2023-03-30 11:33:15 +02:00
parent 747f2c316c
commit 311c98f7f2
20 changed files with 1046 additions and 373 deletions

View File

@ -11,7 +11,7 @@ from typing import Union, Dict
from meow_base.core.base_pattern import BasePattern
from meow_base.core.base_recipe import BaseRecipe
from meow_base.core.base_rule import BaseRule
from meow_base.core.rule import Rule
from meow_base.core.correctness.vars import VALID_CHANNELS, \
VALID_MONITOR_NAME_CHARS, get_drt_imp_msg
from meow_base.core.correctness.validation import check_implementation, \
@ -29,7 +29,7 @@ class BaseMonitor:
# A collection of recipes
_recipes: Dict[str, BaseRecipe]
# A collection of rules derived from _patterns and _recipes
_rules: Dict[str, BaseRule]
_rules: Dict[str, Rule]
# A channel for sending messages to the runner. Note that this is not
# initialised within the constructor, but within the runner when passed the
# monitor is passed to it.
@ -138,7 +138,7 @@ class BaseMonitor:
Must be implemented by any child process."""
pass
def get_rules(self)->Dict[str,BaseRule]:
def get_rules(self)->Dict[str,Rule]:
"""Function to get a dictionary of all current rule definitions.
Must be implemented by any child process."""
pass

View File

@ -1,85 +0,0 @@
"""
This file contains the base MEOW rule defintion. This should be inherited from
for all rule instances.
Author(s): David Marchant
"""
from sys import modules
from typing import Any
if "BasePattern" not in modules:
from meow_base.core.base_pattern import BasePattern
if "BaseRecipe" not in modules:
from meow_base.core.base_recipe import BaseRecipe
from meow_base.core.correctness.vars import VALID_RULE_NAME_CHARS, \
get_drt_imp_msg
from meow_base.core.correctness.validation import valid_string, check_type, \
check_implementation
class BaseRule:
# A unique identifier for the rule
name:str
# A pattern to be used in rule triggering
pattern:BasePattern
# A recipe to be used in rule execution
recipe:BaseRecipe
# The string name of the pattern class that can be used to create this rule
pattern_type:str=""
# The string name of the recipe class that can be used to create this rule
recipe_type:str=""
def __init__(self, name:str, pattern:BasePattern, recipe:BaseRecipe):
"""BaseRule Constructor. This will check that any class inheriting
from it implements its validation functions. It will then call these on
the input parameters."""
check_implementation(type(self)._is_valid_pattern, BaseRule)
check_implementation(type(self)._is_valid_recipe, BaseRule)
self.__check_types_set()
self._is_valid_name(name)
self.name = name
self._is_valid_pattern(pattern)
self.pattern = pattern
self._is_valid_recipe(recipe)
self.recipe = recipe
check_type(pattern, BasePattern, hint="BaseRule.pattern")
check_type(recipe, BaseRecipe, hint="BaseRule.recipe")
if pattern.recipe != recipe.name:
raise ValueError(f"Cannot create Rule {name}. Pattern "
f"{pattern.name} does not identify Recipe {recipe.name}. It "
f"uses {pattern.recipe}")
def __new__(cls, *args, **kwargs):
"""A check that this base class is not instantiated itself, only
inherited from"""
if cls is BaseRule:
msg = get_drt_imp_msg(BaseRule)
raise TypeError(msg)
return object.__new__(cls)
def _is_valid_name(self, name:str)->None:
"""Validation check for 'name' variable from main constructor. Is
automatically called during initialisation. This does not need to be
overridden by child classes."""
valid_string(name, VALID_RULE_NAME_CHARS)
def _is_valid_pattern(self, pattern:Any)->None:
"""Validation check for 'pattern' variable from main constructor. Must
be implemented by any child class."""
pass
def _is_valid_recipe(self, recipe:Any)->None:
"""Validation check for 'recipe' variable from main constructor. Must
be implemented by any child class."""
pass
def __check_types_set(self)->None:
"""Validation check that the self.pattern_type and self.recipe_type
attributes have been set in a child class."""
if self.pattern_type == "":
raise AttributeError(f"Rule Class '{self.__class__.__name__}' "
"does not set a pattern_type.")
if self.recipe_type == "":
raise AttributeError(f"Rule Class '{self.__class__.__name__}' "
"does not set a recipe_type.")

View File

@ -2,7 +2,7 @@
from datetime import datetime
from typing import Any, Dict, Type
from meow_base.core.base_rule import BaseRule
from meow_base.core.rule import Rule
from meow_base.core.correctness.validation import check_type
from meow_base.core.correctness.vars import EVENT_TYPE, EVENT_PATH, \
JOB_EVENT, JOB_TYPE, JOB_ID, JOB_PATTERN, JOB_RECIPE, JOB_RULE, \
@ -13,7 +13,7 @@ EVENT_KEYS = {
EVENT_TYPE: str,
EVENT_PATH: str,
# Should be a Rule but can't import here due to circular dependencies
EVENT_RULE: BaseRule
EVENT_RULE: Rule
}
WATCHDOG_EVENT_KEYS = {

View File

@ -86,6 +86,7 @@ DEFAULT_JOB_OUTPUT_DIR = "job_output"
# meow jobs
JOB_TYPE = "job_type"
JOB_TYPE_BASH = "bash"
JOB_TYPE_PYTHON = "python"
JOB_TYPE_PAPERMILL = "papermill"
PYTHON_FUNC = "func"
@ -94,12 +95,17 @@ JOB_TYPES = {
JOB_TYPE_PAPERMILL: [
"base.ipynb",
"job.ipynb",
"result.ipynb",
"result.ipynb"
],
JOB_TYPE_PYTHON: [
"base.py",
"job.py",
"result.py",
"result.py"
],
JOB_TYPE_BASH: [
"base.sh",
"job.sh",
"result.sh"
]
}

49
core/rule.py Normal file
View File

@ -0,0 +1,49 @@
"""
This file contains the MEOW rule defintion.
Author(s): David Marchant
"""
from sys import modules
from typing import Any
if "BasePattern" not in modules:
from meow_base.core.base_pattern import BasePattern
if "BaseRecipe" not in modules:
from meow_base.core.base_recipe import BaseRecipe
from meow_base.core.correctness.vars import VALID_RULE_NAME_CHARS, \
get_drt_imp_msg
from meow_base.core.correctness.validation import valid_string, check_type, \
check_implementation
from meow_base.functionality.naming import generate_rule_id
class Rule:
# A unique identifier for the rule
name:str
# A pattern to be used in rule triggering
pattern:BasePattern
# A recipe to be used in rule execution
recipe:BaseRecipe
def __init__(self, pattern:BasePattern, recipe:BaseRecipe, name:str=""):
"""Rule Constructor. This will check that any class inheriting
from it implements its validation functions. It will then call these on
the input parameters."""
if not name:
name = generate_rule_id()
self._is_valid_name(name)
self.name = name
check_type(pattern, BasePattern, hint="Rule.pattern")
self.pattern = pattern
check_type(recipe, BaseRecipe, hint="Rule.recipe")
self.recipe = recipe
if pattern.recipe != recipe.name:
raise ValueError(f"Cannot create Rule {name}. Pattern "
f"{pattern.name} does not identify Recipe {recipe.name}. It "
f"uses {pattern.recipe}")
def _is_valid_name(self, name:str)->None:
"""Validation check for 'name' variable from main constructor. Is
automatically called during initialisation."""
valid_string(name, VALID_RULE_NAME_CHARS)