reformatted imports to work better on other machines, plus added benchmarking to project

This commit is contained in:
PatchOfScotland
2023-03-13 11:32:45 +01:00
parent c01df1b190
commit 40ed98000b
48 changed files with 907 additions and 173 deletions

4
.gitignore vendored
View File

@ -58,6 +58,10 @@ tests/test_data
tests/job_output tests/job_output
tests/job_queue tests/job_queue
tests/Backup* tests/Backup*
benchmarking/benchmark_base
benchmarking/job_output
benchmarking/job_queue
benchmarking/result*
# hdf5 # hdf5
*.h5 *.h5

34
benchmarking/mrme.py Normal file
View File

@ -0,0 +1,34 @@
from meow_base.patterns import FileEventPattern
from meow_base.recipes import getRecipeFromNotebook
from shared import run_test, MRME
def multiple_rules_multiple_events(job_count:int, REPEATS, job_counter, requested_jobs, runtime_start):
patterns = {}
for i in range(job_count):
pattern = FileEventPattern(
f"pattern_{i}",
f"testing/file_{i}.txt",
"recipe_one",
"input"
)
patterns[pattern.name] = pattern
recipe = getRecipeFromNotebook("recipe_one", "test.ipynb")
recipes = {
recipe.name: recipe
}
run_test(
patterns,
recipes,
job_count,
job_count,
REPEATS,
job_counter,
requested_jobs,
runtime_start,
signature=MRME
)

34
benchmarking/mrse.py Normal file
View File

@ -0,0 +1,34 @@
from meow_base.patterns import FileEventPattern
from meow_base.recipes import getRecipeFromNotebook
from shared import run_test, MRSE
def multiple_rules_single_event(job_count:int, REPEATS, job_counter, requested_jobs, runtime_start):
patterns = {}
for i in range(job_count):
pattern = FileEventPattern(
f"pattern_{i}",
f"testing/*",
"recipe_one",
"input"
)
patterns[pattern.name] = pattern
recipe = getRecipeFromNotebook("recipe_one", "test.ipynb")
recipes = {
recipe.name: recipe
}
run_test(
patterns,
recipes,
1,
job_count,
REPEATS,
job_counter,
requested_jobs,
runtime_start,
signature=MRSE
)

175
benchmarking/run_all.py Normal file
View File

@ -0,0 +1,175 @@
import matplotlib.pyplot as pyplot
import numpy
import sys
import time
import os
from shared import JOBS_COUNTS, REPEATS, TESTS, MRME, MRSE, SRME, SRSEP, SRSES, RESULTS_DIR, BASE, GRAPH_FILENAME
from mrme import multiple_rules_multiple_events
from mrse import multiple_rules_single_event
from srme import single_rule_multiple_events
from srsep import single_rule_single_event_parallel
from srsps import single_rule_single_event_sequential
from meow_base.core.correctness.vars import DEFAULT_JOB_OUTPUT_DIR, DEFAULT_JOB_QUEUE_DIR
from meow_base.functionality.file_io import rmtree
LINE_KEYS = {
SRSES: ('x','#a1467e'),
SRME: ('.','#896cff'),
MRME: ('d','#5983b0'),
MRSE: ('P','#ff6cbe'),
SRSEP: ('*','#3faf46'),
}
def run_tests():
rmtree(RESULTS_DIR)
requested_jobs=0
for job_count in JOBS_COUNTS:
requested_jobs += job_count * REPEATS * len(TESTS)
print(f"requested_jobs: {requested_jobs}")
runtime_start=time.time()
job_counter=0
for job_count in JOBS_COUNTS:
for test in TESTS:
if test == MRME:
multiple_rules_multiple_events(job_count, REPEATS, job_counter, requested_jobs, runtime_start)
job_counter += job_count * REPEATS
elif test == MRSE:
multiple_rules_single_event(job_count, REPEATS, job_counter, requested_jobs, runtime_start)
job_counter += job_count * REPEATS
elif test == SRME:
single_rule_multiple_events(job_count, REPEATS, job_counter, requested_jobs, runtime_start)
job_counter += job_count * REPEATS
elif test == SRSEP:
single_rule_single_event_parallel(job_count, REPEATS, job_counter, requested_jobs, runtime_start)
job_counter += job_count * REPEATS
elif test == SRSES:
single_rule_single_event_sequential(job_count, REPEATS, job_counter, requested_jobs, runtime_start)
job_counter += job_count * REPEATS
print(f"All tests completed in: {str(time.time()-runtime_start)}")
def get_meow_graph(results_dir):
lines = []
for run_type in os.listdir(results_dir):
#if run_type == 'single_Pattern_single_file_sequential':
# continue
# lines.append((f'scheduling {run_type}', [], 'solid'))
lines.append((run_type, [], 'solid'))
run_type_path = os.path.join(results_dir, run_type)
for job_count in os.listdir(run_type_path):
results_path = os.path.join(run_type_path, job_count, 'results.txt')
with open(results_path, 'r') as f_in:
data = f_in.readlines()
scheduling_duration = 0
for line in data:
if "Average schedule time: " in line:
scheduling_duration = float(line.replace("Average schedule time: ", ''))
lines[-1][1].append((job_count, scheduling_duration))
lines[-1][1].sort(key=lambda y: float(y[0]))
return lines
def make_plot(lines, graph_path, title, logged):
w = 10
h = 4
linecount = 0
columns = 1
pyplot.figure(figsize=(w, h))
for l in range(len(lines)):
x_values = numpy.asarray([float(i[0]) for i in lines[l][1]])
y_values = numpy.asarray([float(i[1]) for i in lines[l][1]])
# Remove this check to always display lines
if lines[l][2] == 'solid':
pyplot.plot(x_values, y_values, label=lines[l][0], linestyle=lines[l][2], marker=LINE_KEYS[lines[l][0]][0], color=LINE_KEYS[lines[l][0]][1])
linecount += 1
columns = int(linecount/3) + 1
pyplot.xlabel("Number of jobs scheduled")
pyplot.ylabel("Time taken (seconds)")
pyplot.title(title)
handles, labels = pyplot.gca().get_legend_handles_labels()
# legend_order = [2, 4, 0, 1, 3]
# pyplot.legend([handles[i] for i in legend_order], [labels[i] for i in legend_order])
pyplot.legend(ncol=columns, prop={'size': 12})
if logged:
pyplot.yscale('log')
x_ticks = []
for tick in x_values:
label = int(tick)
if tick <= 100 and tick % 20 == 0:
label = f"\n{int(tick)}"
x_ticks.append(label)
pyplot.xticks(x_values, x_ticks)
pyplot.savefig(graph_path, format='pdf', bbox_inches='tight')
def make_both_plots(lines, path, title, log=True):
make_plot(lines, path, title, False)
if log:
logged_path = path[:path.index(".pdf")] + "_logged" + path[path.index(".pdf"):]
make_plot(lines, logged_path, title, True)
def make_graphs():
lines = get_meow_graph(RESULTS_DIR)
make_both_plots(lines, "result.pdf", "MiG scheduling overheads on the Threadripper")
average_lines = []
all_delta_lines = []
no_spsfs_delta_lines = []
for line_signature, line_values, lines_style in lines:
if lines_style == 'solid':
averages = [(i, v/float(i)) for i, v in line_values]
average_lines.append((line_signature, averages, lines_style))
if line_signature not in ["total single_Pattern_single_file_sequential", "scheduling single_Pattern_single_file_sequential_jobs", "SPSFS"]:
deltas = []
for i in range(len(line_values)-1):
deltas.append( (line_values[i+1][0], (averages[i+1][1]-averages[i][1]) / (float(averages[i+1][0])-float(averages[i][0])) ) )
no_spsfs_delta_lines.append((line_signature, deltas, lines_style))
deltas = []
for i in range(len(line_values)-1):
deltas.append( (line_values[i+1][0], (averages[i+1][1]-averages[i][1]) / (float(averages[i+1][0])-float(averages[i][0])) ) )
all_delta_lines.append((line_signature, deltas, lines_style))
make_both_plots(average_lines, "result_averaged.pdf", "Per-job MiG scheduling overheads on the Threadripper")
make_both_plots(all_delta_lines, "result_deltas.pdf", "Difference in per-job MiG scheduling overheads on the Threadripper", log=False)
if __name__ == '__main__':
try:
run_tests()
make_graphs()
rmtree(DEFAULT_JOB_QUEUE_DIR)
rmtree(DEFAULT_JOB_OUTPUT_DIR)
rmtree(BASE)
except KeyboardInterrupt as ki:
try:
sys.exit(1)
except SystemExit:
os._exit(1)

View File

@ -0,0 +1,69 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"INPUT_FILE = 'file_0.txt'\n",
"MAX_COUNT = 100"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"with open(INPUT_FILE, 'r') as f:\n",
" data = int(f.read())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"read in: \"+ str(data))\n",
"print(\"writing out: \"+ str(data+1))"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [],
"source": [
"if data+1 < MAX_COUNT:\n",
" with open(INPUT_FILE.replace(str(data), str(data+1)), 'w') as f:\n",
" f.write(str(data+1))"
]
}
],
"metadata": {
"interpreter": {
"hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.5"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

225
benchmarking/shared.py Normal file
View File

@ -0,0 +1,225 @@
import datetime
import io
import os
import pathlib
import time
import yaml
from typing import Any, Dict, Tuple
from meow_base.core.correctness.vars import DEFAULT_JOB_OUTPUT_DIR, DEFAULT_JOB_QUEUE_DIR
from meow_base.core.runner import MeowRunner
from meow_base.patterns.file_event_pattern import WatchdogMonitor
from meow_base.recipes.jupyter_notebook_recipe import PapermillHandler
from meow_base.conductors import LocalPythonConductor
from meow_base.functionality.file_io import rmtree
RESULTS_DIR = "results"
BASE = "benchmark_base"
GRAPH_FILENAME = "graph.pdf"
REPEATS = 10
JOBS_COUNTS = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 125, 150, 175, 200, 250, 300, 400, 500]
SRME = "single_rule_multiple_events"
MRSE = "multiple_rules_single_event"
SRSEP = "single_rule_single_event_parallel"
MRME = "multiple_rules_multiple_events"
SRSES = "single_rule_single_event_sequential"
TESTS = [
SRME,
MRSE,
SRSEP,
MRME,
# This test will take approx 90% of total time
SRSES
]
class DummyConductor(LocalPythonConductor):
def valid_execute_criteria(self, job:Dict[str,Any])->Tuple[bool,str]:
return False, ">:("
def datetime_to_timestamp(date_time_obj):
return time.mktime(date_time_obj.timetuple()) + float(date_time_obj.microsecond)/1000000
def generate(file_count, file_path, file_type='.txt'):
first_filename = ''
start = time.time()
for i in range(int(file_count)):
filename = file_path + str(i) + file_type
if not first_filename:
first_filename = filename
with open(filename, 'w') as f:
f.write('0')
return first_filename, time.time() - start
def cleanup(jobs, file_out, base_time, gen_time, execution=False):
if not jobs:
return
job_timestamps = []
for job in jobs:
if execution:
with open(f"{DEFAULT_JOB_OUTPUT_DIR}/{job}/job.yml", 'r') as f_in:
data = yaml.load(f_in, Loader=yaml.Loader)
else:
with open(f"{DEFAULT_JOB_QUEUE_DIR}/{job}/job.yml", 'r') as f_in:
data = yaml.load(f_in, Loader=yaml.Loader)
create_datetime = data['create']
create_timestamp = datetime_to_timestamp(create_datetime)
job_timestamps.append((create_timestamp, create_datetime))
job_timestamps.sort(key=lambda y: int(y[0]))
first = job_timestamps[0]
last = job_timestamps[-1]
#dt = datetime.datetime.fromtimestamp(os.path.getctime(base_time), datetime.timezone(datetime.timedelta(hours=0)))
dt = datetime.datetime.fromtimestamp(os.path.getctime(base_time))
# if execution:
# queue_times = []
# execution_times = []
# for j in jobs:
# mrsl_dict = load(os.path.join(mrsl_dir, j))#
#
# queue_times.append(time.mktime(mrsl_dict['EXECUTING_TIMESTAMP']) - time.mktime(mrsl_dict['QUEUED_TIMESTAMP']))
# execution_times.append(time.mktime(mrsl_dict['FINISHED_TIMESTAMP']) - time.mktime(mrsl_dict['EXECUTING_TIMESTAMP']))
pathlib.Path(os.path.dirname(file_out)).mkdir(parents=True, exist_ok=True)
with open(file_out, 'w') as f_out:
f_out.write("Job count: "+ str(len(jobs)) +"\n")
f_out.write("Generation time: "+ str(round(gen_time, 5)) +"\n")
f_out.write("First trigger: "+ str(dt) +"\n")
f_out.write("First scheduling datetime: "+ str(first[1]) +"\n")
f_out.write("Last scheduling datetime: "+ str(last[1]) +"\n")
f_out.write("First scheduling unixtime: "+ str(first[0]) +"\n")
f_out.write("First scheduling unixtime: "+ str(last[0]) +"\n")
f_out.write("Scheduling difference (seconds): "+ str(round(last[0] - first[0], 3)) +"\n")
f_out.write("Initial scheduling delay (seconds): "+ str(round(first[0] - os.path.getctime(base_time), 3)) +"\n")
total_time = round(last[0] - os.path.getctime(base_time), 3)
f_out.write("Total scheduling delay (seconds): "+ str(total_time) +"\n")
# if execution:
# f_out.write("Average execution time (seconds): "+ str(round(mean(execution_times), 3)) +"\n")
# f_out.write("Max execution time (seconds): "+ str(round(max(execution_times), 3)) +"\n")
# f_out.write("Min execution time (seconds): "+ str(round(min(execution_times), 3)) +"\n")
# f_out.write("Average queueing delay (seconds): "+ str(round(mean(queue_times), 3)) +"\n")
# f_out.write("Max queueing delay (seconds): "+ str(round(max(queue_times), 3)) +"\n")
# f_out.write("Min queueing delay (seconds): "+ str(round(min(queue_times), 3)) +"\n")
# queue_times.remove(max(queue_times))
# f_out.write("Average excluded queueing delay (seconds): "+ str(round(mean(queue_times), 3)) +"\n")
return total_time
def mean(l):
return sum(l)/len(l)
def collate_results(base_results_dir):
scheduling_delays = []
for run in os.listdir(base_results_dir):
if run != 'results.txt':
with open(os.path.join(base_results_dir, run, 'results.txt'), 'r') as f:
d = f.readlines()
for l in d:
if "Total scheduling delay (seconds): " in l:
scheduling_delays.append(float(l.replace("Total scheduling delay (seconds): ", '')))
with open(os.path.join(base_results_dir, 'results.txt'), 'w') as f:
f.write(f"Average schedule time: {round(mean(scheduling_delays), 3)}\n")
f.write(f"Scheduling times: {scheduling_delays}")
def run_test(patterns, recipes, files_count, expected_job_count, repeats, job_counter, requested_jobs, runtime_start, signature='', execution=False, print_logging=False):
if not os.path.exists(RESULTS_DIR):
os.mkdir(RESULTS_DIR)
# Does not work. left here as reminder
if execution:
os.system("export LC_ALL=C.UTF-8")
os.system("export LANG=C.UTF-8")
for run in range(repeats):
# Ensure complete cleanup from previous run
for f in [BASE, DEFAULT_JOB_QUEUE_DIR, DEFAULT_JOB_OUTPUT_DIR]:
if os.path.exists(f):
rmtree(f)
file_base = os.path.join(BASE, 'testing')
pathlib.Path(file_base).mkdir(parents=True, exist_ok=True)
runner_debug_stream = io.StringIO("")
if execution:
runner = MeowRunner(
WatchdogMonitor(BASE, patterns, recipes, settletime=1),
PapermillHandler(),
LocalPythonConductor(),
print=runner_debug_stream,
logging=3
)
else:
runner = MeowRunner(
WatchdogMonitor(BASE, patterns, recipes, settletime=1),
PapermillHandler(),
DummyConductor(),
print=runner_debug_stream,
logging=3
)
# meow.WorkflowRunner(
# VGRID,
# num_workers,
# patterns=patterns,
# recipes=recipes,
# daemon=True,
# start_workers=False,
# retro_active_jobs=False,
# print_logging=print_logging,
# file_logging=False,
# wait_time=1
# )
runner.start()
# Generate triggering files
first_filename, generation_duration = generate(files_count, file_base +"/file_")
idle_loops = 0
total_loops = 0
messages = 0
total_time = expected_job_count * 3
if execution:
total_time = expected_job_count * 5
while idle_loops < 10 and total_loops < total_time:
time.sleep(1)
runner_debug_stream.seek(0)
new_messages = len(runner_debug_stream.readlines())
if messages == new_messages:
idle_loops += 1
else:
idle_loops = 0
messages = new_messages
total_loops += 1
runner.stop()
if execution:
jobs = os.listdir(DEFAULT_JOB_OUTPUT_DIR)
else:
jobs = os.listdir(DEFAULT_JOB_QUEUE_DIR)
results_path = os.path.join(RESULTS_DIR, signature, str(expected_job_count), str(run), 'results.txt')
cleanup(jobs, results_path, first_filename, generation_duration, execution=execution)
print(f"Completed scheduling run {str(run + 1)} of {str(len(jobs))}/{str(expected_job_count)} jobs for '{signature}' {job_counter + expected_job_count*(run+1)}/{requested_jobs} ({str(round(time.time()-runtime_start, 3))}s)")
collate_results(os.path.join(RESULTS_DIR, signature, str(expected_job_count)))

33
benchmarking/srme.py Normal file
View File

@ -0,0 +1,33 @@
from meow_base.patterns import FileEventPattern
from meow_base.recipes import getRecipeFromNotebook
from shared import run_test, SRME
def single_rule_multiple_events(job_count:int, REPEATS, job_counter, requested_jobs, runtime_start):
patterns = {}
pattern = FileEventPattern(
f"pattern_one",
f"testing/*",
"recipe_one",
"input"
)
patterns[pattern.name] = pattern
recipe = getRecipeFromNotebook("recipe_one", "test.ipynb")
recipes = {
recipe.name: recipe
}
run_test(
patterns,
recipes,
job_count,
job_count,
REPEATS,
job_counter,
requested_jobs,
runtime_start,
signature=SRME
)

35
benchmarking/srsep.py Normal file
View File

@ -0,0 +1,35 @@
from meow_base.patterns import FileEventPattern
from meow_base.recipes import getRecipeFromNotebook
from meow_base.functionality.meow import create_parameter_sweep
from shared import run_test, SRSEP
def single_rule_single_event_parallel(job_count:int, REPEATS, job_counter, requested_jobs, runtime_start):
patterns = {}
pattern = FileEventPattern(
f"pattern_one",
f"testing/*",
"recipe_one",
"input",
sweep=create_parameter_sweep("var", 1, job_count, 1)
)
patterns[pattern.name] = pattern
recipe = getRecipeFromNotebook("recipe_one", "test.ipynb")
recipes = {
recipe.name: recipe
}
run_test(
patterns,
recipes,
1,
job_count,
REPEATS,
job_counter,
requested_jobs,
runtime_start,
signature=SRSEP
)

38
benchmarking/srsps.py Normal file
View File

@ -0,0 +1,38 @@
from meow_base.patterns import FileEventPattern
from meow_base.recipes import getRecipeFromNotebook
from shared import run_test, SRSES
def single_rule_single_event_sequential(job_count:int, REPEATS, job_counter, requested_jobs, runtime_start):
patterns = {}
pattern = FileEventPattern(
f"pattern_one",
f"testing/*",
"recipe_two",
"INPUT_FILE",
parameters={
"MAX_COUNT":job_count
}
)
patterns[pattern.name] = pattern
recipe = getRecipeFromNotebook("recipe_two", "sequential.ipynb")
recipes = {
recipe.name: recipe
}
run_test(
patterns,
recipes,
1,
job_count,
REPEATS,
job_counter,
requested_jobs,
runtime_start,
signature=SRSES,
execution=True,
print_logging=False
)

47
benchmarking/test.ipynb Normal file
View File

@ -0,0 +1,47 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31mFailed to start the Kernel. \n",
"Failed to start the Kernel 'Python 3.6.9 64-bit'. \n",
"View Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details. Kernel has not been started"
]
}
],
"source": [
"print('this is some outpug ')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"interpreter": {
"hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
},
"kernelspec": {
"display_name": "Python 3.6.9 64-bit",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.6.9"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@ -1,2 +1,2 @@
from conductors.local_python_conductor import LocalPythonConductor from .local_python_conductor import LocalPythonConductor

View File

@ -11,14 +11,14 @@ import shutil
from datetime import datetime from datetime import datetime
from typing import Any, Tuple, Dict from typing import Any, Tuple, Dict
from core.base_conductor import BaseConductor from meow_base.core.base_conductor import BaseConductor
from core.correctness.meow import valid_job from meow_base.core.correctness.meow import valid_job
from core.correctness.vars import JOB_TYPE_PYTHON, PYTHON_FUNC, JOB_STATUS, \ from meow_base.core.correctness.vars import JOB_TYPE_PYTHON, PYTHON_FUNC, JOB_STATUS, \
STATUS_RUNNING, JOB_START_TIME, META_FILE, BACKUP_JOB_ERROR_FILE, \ STATUS_RUNNING, JOB_START_TIME, META_FILE, BACKUP_JOB_ERROR_FILE, \
STATUS_DONE, JOB_END_TIME, STATUS_FAILED, JOB_ERROR, \ STATUS_DONE, JOB_END_TIME, STATUS_FAILED, JOB_ERROR, \
JOB_TYPE, JOB_TYPE_PAPERMILL, DEFAULT_JOB_QUEUE_DIR, DEFAULT_JOB_OUTPUT_DIR JOB_TYPE, JOB_TYPE_PAPERMILL, DEFAULT_JOB_QUEUE_DIR, DEFAULT_JOB_OUTPUT_DIR
from core.correctness.validation import valid_dir_path from meow_base.core.correctness.validation import valid_dir_path
from functionality.file_io import make_dir, read_yaml, write_file, write_yaml from meow_base.functionality.file_io import make_dir, read_yaml, write_file, write_yaml
class LocalPythonConductor(BaseConductor): class LocalPythonConductor(BaseConductor):
def __init__(self, job_queue_dir:str=DEFAULT_JOB_QUEUE_DIR, def __init__(self, job_queue_dir:str=DEFAULT_JOB_QUEUE_DIR,

0
core/__init__.py Normal file
View File

View File

@ -8,8 +8,8 @@ Author(s): David Marchant
from typing import Any, Tuple, Dict from typing import Any, Tuple, Dict
from core.correctness.vars import get_drt_imp_msg from meow_base.core.correctness.vars import get_drt_imp_msg
from core.correctness.validation import check_implementation from meow_base.core.correctness.validation import check_implementation
class BaseConductor: class BaseConductor:

View File

@ -8,8 +8,8 @@ Author(s): David Marchant
from typing import Any, Tuple, Dict from typing import Any, Tuple, Dict
from core.correctness.vars import get_drt_imp_msg, VALID_CHANNELS from meow_base.core.correctness.vars import get_drt_imp_msg, VALID_CHANNELS
from core.correctness.validation import check_implementation from meow_base.core.correctness.validation import check_implementation
class BaseHandler: class BaseHandler:

View File

@ -9,12 +9,12 @@ Author(s): David Marchant
from copy import deepcopy from copy import deepcopy
from typing import Union, Dict from typing import Union, Dict
from core.base_pattern import BasePattern from meow_base.core.base_pattern import BasePattern
from core.base_recipe import BaseRecipe from meow_base.core.base_recipe import BaseRecipe
from core.base_rule import BaseRule from meow_base.core.base_rule import BaseRule
from core.correctness.vars import get_drt_imp_msg, VALID_CHANNELS from meow_base.core.correctness.vars import get_drt_imp_msg, VALID_CHANNELS
from core.correctness.validation import check_implementation from meow_base.core.correctness.validation import check_implementation
from functionality.meow import create_rules from meow_base.functionality.meow import create_rules
class BaseMonitor: class BaseMonitor:

View File

@ -10,9 +10,9 @@ import itertools
from typing import Any, Union, Tuple, Dict, List from typing import Any, Union, Tuple, Dict, List
from core.correctness.vars import get_drt_imp_msg, \ from meow_base.core.correctness.vars import get_drt_imp_msg, \
VALID_PATTERN_NAME_CHARS, SWEEP_JUMP, SWEEP_START, SWEEP_STOP VALID_PATTERN_NAME_CHARS, SWEEP_JUMP, SWEEP_START, SWEEP_STOP
from core.correctness.validation import valid_string, check_type, \ from meow_base.core.correctness.validation import valid_string, check_type, \
check_implementation, valid_dict check_implementation, valid_dict

View File

@ -8,8 +8,8 @@ Author(s): David Marchant
from typing import Any, Dict from typing import Any, Dict
from core.correctness.vars import get_drt_imp_msg, VALID_RECIPE_NAME_CHARS from meow_base.core.correctness.vars import get_drt_imp_msg, VALID_RECIPE_NAME_CHARS
from core.correctness.validation import valid_string, check_implementation from meow_base.core.correctness.validation import valid_string, check_implementation
class BaseRecipe: class BaseRecipe:

View File

@ -10,11 +10,11 @@ from sys import modules
from typing import Any from typing import Any
if "BasePattern" not in modules: if "BasePattern" not in modules:
from core.base_pattern import BasePattern from meow_base.core.base_pattern import BasePattern
if "BaseRecipe" not in modules: if "BaseRecipe" not in modules:
from core.base_recipe import BaseRecipe from meow_base.core.base_recipe import BaseRecipe
from core.correctness.vars import get_drt_imp_msg, VALID_RULE_NAME_CHARS from meow_base.core.correctness.vars import get_drt_imp_msg, VALID_RULE_NAME_CHARS
from core.correctness.validation import valid_string, check_type, \ from meow_base.core.correctness.validation import valid_string, check_type, \
check_implementation check_implementation

View File

@ -2,9 +2,9 @@
from datetime import datetime from datetime import datetime
from typing import Any, Dict, Type from typing import Any, Dict, Type
from core.base_rule import BaseRule from meow_base.core.base_rule import BaseRule
from core.correctness.validation import check_type from meow_base.core.correctness.validation import check_type
from core.correctness.vars import EVENT_TYPE, EVENT_PATH, JOB_EVENT, \ from meow_base.core.correctness.vars import EVENT_TYPE, EVENT_PATH, JOB_EVENT, \
JOB_TYPE, JOB_ID, JOB_PATTERN, JOB_RECIPE, JOB_RULE, JOB_STATUS, \ JOB_TYPE, JOB_ID, JOB_PATTERN, JOB_RECIPE, JOB_RULE, JOB_STATUS, \
JOB_CREATE_TIME, EVENT_RULE, WATCHDOG_BASE, WATCHDOG_HASH JOB_CREATE_TIME, EVENT_RULE, WATCHDOG_BASE, WATCHDOG_HASH

View File

@ -11,7 +11,7 @@ from os.path import sep, exists, isfile, isdir, dirname
from typing import Any, _SpecialForm, Union, Type, Dict, List, \ from typing import Any, _SpecialForm, Union, Type, Dict, List, \
get_origin, get_args get_origin, get_args
from core.correctness.vars import VALID_PATH_CHARS, get_not_imp_msg from meow_base.core.correctness.vars import VALID_PATH_CHARS, get_not_imp_msg
def check_type(variable:Any, expected_type:Type, alt_types:List[Type]=[], def check_type(variable:Any, expected_type:Type, alt_types:List[Type]=[],
or_none:bool=False, hint:str="")->None: or_none:bool=False, hint:str="")->None:

View File

@ -14,16 +14,16 @@ from multiprocessing import Pipe
from random import randrange from random import randrange
from typing import Any, Union, Dict, List from typing import Any, Union, Dict, List
from core.base_conductor import BaseConductor from meow_base.core.base_conductor import BaseConductor
from core.base_handler import BaseHandler from meow_base.core.base_handler import BaseHandler
from core.base_monitor import BaseMonitor from meow_base.core.base_monitor import BaseMonitor
from core.correctness.vars import DEBUG_WARNING, DEBUG_INFO, EVENT_TYPE, \ from meow_base.core.correctness.vars import DEBUG_WARNING, DEBUG_INFO, EVENT_TYPE, \
VALID_CHANNELS, META_FILE, DEFAULT_JOB_OUTPUT_DIR, DEFAULT_JOB_QUEUE_DIR, \ VALID_CHANNELS, META_FILE, DEFAULT_JOB_OUTPUT_DIR, DEFAULT_JOB_QUEUE_DIR, \
EVENT_PATH EVENT_PATH
from core.correctness.validation import check_type, valid_list, valid_dir_path from meow_base.core.correctness.validation import check_type, valid_list, valid_dir_path
from functionality.debug import setup_debugging, print_debug from meow_base.functionality.debug import setup_debugging, print_debug
from functionality.file_io import make_dir, read_yaml from meow_base.functionality.file_io import make_dir, read_yaml
from functionality.process_io import wait from meow_base.functionality.process_io import wait
class MeowRunner: class MeowRunner:
@ -112,6 +112,7 @@ class MeowRunner:
if self._stop_mon_han_pipe[0] in ready: if self._stop_mon_han_pipe[0] in ready:
return return
else: else:
handled = False
for from_monitor in self.from_monitors: for from_monitor in self.from_monitors:
if from_monitor in ready: if from_monitor in ready:
# Read event from the monitor channel # Read event from the monitor channel
@ -136,13 +137,25 @@ class MeowRunner:
# If we've only one handler, use that # If we've only one handler, use that
if len(valid_handlers) == 1: if len(valid_handlers) == 1:
handler = valid_handlers[0] handler = valid_handlers[0]
handled = True
self.handle_event(handler, event) self.handle_event(handler, event)
break
# If multiple handlers then randomly pick one # If multiple handlers then randomly pick one
else: elif len(valid_handlers) > 1:
handler = valid_handlers[ handler = valid_handlers[
randrange(len(valid_handlers)) randrange(len(valid_handlers))
] ]
handled = True
self.handle_event(handler, event) self.handle_event(handler, event)
break
if not handled:
print_debug(
self._print_target,
self.debug_level,
"Could not determine handler for event.",
DEBUG_INFO
)
def run_handler_conductor_interaction(self)->None: def run_handler_conductor_interaction(self)->None:
"""Function to be run in its own thread, to handle any inbound messages """Function to be run in its own thread, to handle any inbound messages
@ -156,6 +169,7 @@ class MeowRunner:
if self._stop_han_con_pipe[0] in ready: if self._stop_han_con_pipe[0] in ready:
return return
else: else:
executed = False
for from_handler in self.from_handlers: for from_handler in self.from_handlers:
if from_handler in ready: if from_handler in ready:
# Read job directory from the handler channel # Read job directory from the handler channel
@ -188,13 +202,26 @@ class MeowRunner:
# If we've only one conductor, use that # If we've only one conductor, use that
if len(valid_conductors) == 1: if len(valid_conductors) == 1:
conductor = valid_conductors[0] conductor = valid_conductors[0]
executed = True
self.execute_job(conductor, job_dir) self.execute_job(conductor, job_dir)
break
# If multiple handlers then randomly pick one # If multiple handlers then randomly pick one
else: elif len(valid_conductors) > 1:
conductor = valid_conductors[ conductor = valid_conductors[
randrange(len(valid_conductors)) randrange(len(valid_conductors))
] ]
executed = True
self.execute_job(conductor, job_dir) self.execute_job(conductor, job_dir)
break
# TODO determine something more useful to do here
if not executed:
print_debug(
self._print_target,
self.debug_level,
f"No conductor could be found for job {job_dir}",
DEBUG_INFO
)
def handle_event(self, handler:BaseHandler, event:Dict[str,Any])->None: def handle_event(self, handler:BaseHandler, event:Dict[str,Any])->None:
"""Function for a given handler to handle a given event, without """Function for a given handler to handle a given event, without

View File

View File

@ -6,8 +6,8 @@ Author(s): David Marchant
from typing import Any, Tuple from typing import Any, Tuple
from core.correctness.validation import check_type from meow_base.core.correctness.validation import check_type
from core.correctness.vars import DEBUG_INFO, DEBUG_WARNING from meow_base.core.correctness.vars import DEBUG_INFO, DEBUG_WARNING
def setup_debugging(print:Any=None, logging:int=0)->Tuple[Any,int]: def setup_debugging(print:Any=None, logging:int=0)->Tuple[Any,int]:

View File

@ -11,7 +11,7 @@ from os import makedirs, remove, rmdir, walk
from os.path import exists, isfile, join from os.path import exists, isfile, join
from typing import Any, Dict, List from typing import Any, Dict, List
from core.correctness.validation import valid_path from meow_base.core.correctness.validation import valid_path
def make_dir(path:str, can_exist:bool=True, ensure_clean:bool=False): def make_dir(path:str, can_exist:bool=True, ensure_clean:bool=False):

View File

@ -6,8 +6,8 @@ Author(s): David Marchant
from hashlib import sha256 from hashlib import sha256
from core.correctness.vars import HASH_BUFFER_SIZE, SHA256 from meow_base.core.correctness.vars import HASH_BUFFER_SIZE, SHA256
from core.correctness.validation import check_type, valid_existing_file_path from meow_base.core.correctness.validation import check_type, valid_existing_file_path
def _get_file_sha256(file_path): def _get_file_sha256(file_path):
sha256_hash = sha256() sha256_hash = sha256()

View File

@ -8,16 +8,16 @@ from datetime import datetime
from os.path import basename, dirname, relpath, splitext from os.path import basename, dirname, relpath, splitext
from typing import Any, Dict, Union, List from typing import Any, Dict, Union, List
from core.base_pattern import BasePattern from meow_base.core.base_pattern import BasePattern
from core.base_recipe import BaseRecipe from meow_base.core.base_recipe import BaseRecipe
from core.base_rule import BaseRule from meow_base.core.base_rule import BaseRule
from core.correctness.validation import check_type, valid_dict, valid_list from meow_base.core.correctness.validation import check_type, valid_dict, valid_list
from core.correctness.vars import EVENT_PATH, EVENT_RULE, EVENT_TYPE, \ from meow_base.core.correctness.vars import EVENT_PATH, EVENT_RULE, EVENT_TYPE, \
EVENT_TYPE_WATCHDOG, JOB_CREATE_TIME, JOB_EVENT, JOB_ID, JOB_PATTERN, \ EVENT_TYPE_WATCHDOG, JOB_CREATE_TIME, JOB_EVENT, JOB_ID, JOB_PATTERN, \
JOB_RECIPE, JOB_REQUIREMENTS, JOB_RULE, JOB_STATUS, JOB_TYPE, \ JOB_RECIPE, JOB_REQUIREMENTS, JOB_RULE, JOB_STATUS, JOB_TYPE, \
STATUS_QUEUED, WATCHDOG_BASE, WATCHDOG_HASH, SWEEP_JUMP, SWEEP_START, \ STATUS_QUEUED, WATCHDOG_BASE, WATCHDOG_HASH, SWEEP_JUMP, SWEEP_START, \
SWEEP_STOP SWEEP_STOP
from functionality.naming import generate_job_id, generate_rule_id from meow_base.functionality.naming import generate_job_id, generate_rule_id
# mig trigger keyword replacements # mig trigger keyword replacements
KEYWORD_PATH = "{PATH}" KEYWORD_PATH = "{PATH}"
@ -208,7 +208,7 @@ def create_rule(pattern:BasePattern, recipe:BaseRecipe,
# TODO fix me # TODO fix me
# Imported here to avoid circular imports at top of file # Imported here to avoid circular imports at top of file
import rules import meow_base.rules
all_rules = { all_rules = {
(r.pattern_type, r.recipe_type):r for r in BaseRule.__subclasses__() (r.pattern_type, r.recipe_type):r for r in BaseRule.__subclasses__()
} }

View File

@ -7,7 +7,7 @@ Author(s): David Marchant
from typing import List from typing import List
from random import SystemRandom from random import SystemRandom
from core.correctness.vars import CHAR_LOWERCASE, CHAR_UPPERCASE from meow_base.core.correctness.vars import CHAR_LOWERCASE, CHAR_UPPERCASE
#TODO Make this guaranteed unique #TODO Make this guaranteed unique

View File

@ -10,7 +10,7 @@ from os import getenv
from papermill.translators import papermill_translators from papermill.translators import papermill_translators
from typing import Any, Dict, List from typing import Any, Dict, List
from core.correctness.validation import check_script, check_type from meow_base.core.correctness.validation import check_script, check_type
# Adapted from: https://github.com/rasmunk/notebook_parameterizer # Adapted from: https://github.com/rasmunk/notebook_parameterizer
def parameterize_jupyter_notebook(jupyter_notebook:Dict[str,Any], def parameterize_jupyter_notebook(jupyter_notebook:Dict[str,Any],

View File

@ -12,7 +12,7 @@ from multiprocessing.connection import Connection, wait as multi_wait
if osName == 'nt': if osName == 'nt':
from multiprocessing.connection import PipeConnection from multiprocessing.connection import PipeConnection
from multiprocessing.queues import Queue from multiprocessing.queues import Queue
from core.correctness.vars import VALID_CHANNELS from meow_base.core.correctness.vars import VALID_CHANNELS
def wait(inputs:List[VALID_CHANNELS])->List[VALID_CHANNELS]: def wait(inputs:List[VALID_CHANNELS])->List[VALID_CHANNELS]:

View File

@ -11,7 +11,7 @@ from os.path import basename
from sys import version_info, prefix, base_prefix from sys import version_info, prefix, base_prefix
from typing import Any, Dict, List, Tuple, Union from typing import Any, Dict, List, Tuple, Union
from core.correctness.validation import check_type from meow_base.core.correctness.validation import check_type
REQUIREMENT_PYTHON = "python" REQUIREMENT_PYTHON = "python"
REQ_PYTHON_MODULES = "modules" REQ_PYTHON_MODULES = "modules"

View File

@ -1,2 +1,2 @@
from patterns.file_event_pattern import FileEventPattern, WatchdogMonitor from .file_event_pattern import FileEventPattern, WatchdogMonitor

View File

@ -18,19 +18,19 @@ from typing import Any, Union, Dict, List
from watchdog.observers import Observer from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler from watchdog.events import PatternMatchingEventHandler
from core.base_recipe import BaseRecipe from meow_base.core.base_recipe import BaseRecipe
from core.base_monitor import BaseMonitor from meow_base.core.base_monitor import BaseMonitor
from core.base_pattern import BasePattern from meow_base.core.base_pattern import BasePattern
from core.base_rule import BaseRule from meow_base.core.base_rule import BaseRule
from core.correctness.validation import check_type, valid_string, \ from meow_base.core.correctness.validation import check_type, valid_string, \
valid_dict, valid_list, valid_path, valid_dir_path valid_dict, valid_list, valid_path, valid_dir_path
from core.correctness.vars import VALID_RECIPE_NAME_CHARS, \ from meow_base.core.correctness.vars import VALID_RECIPE_NAME_CHARS, \
VALID_VARIABLE_NAME_CHARS, FILE_EVENTS, FILE_CREATE_EVENT, \ VALID_VARIABLE_NAME_CHARS, FILE_EVENTS, FILE_CREATE_EVENT, \
FILE_MODIFY_EVENT, FILE_MOVED_EVENT, DEBUG_INFO, \ FILE_MODIFY_EVENT, FILE_MOVED_EVENT, DEBUG_INFO, \
FILE_RETROACTIVE_EVENT, SHA256, VALID_PATH_CHARS, FILE_CLOSED_EVENT FILE_RETROACTIVE_EVENT, SHA256, VALID_PATH_CHARS, FILE_CLOSED_EVENT
from functionality.debug import setup_debugging, print_debug from meow_base.functionality.debug import setup_debugging, print_debug
from functionality.hashing import get_file_hash from meow_base.functionality.hashing import get_file_hash
from functionality.meow import create_rule, create_watchdog_event from meow_base.functionality.meow import create_rule, create_watchdog_event
# Events that are monitored by default # Events that are monitored by default
_DEFAULT_MASK = [ _DEFAULT_MASK = [

View File

@ -1,4 +1,4 @@
from recipes.jupyter_notebook_recipe import JupyterNotebookRecipe, \ from .jupyter_notebook_recipe import JupyterNotebookRecipe, PapermillHandler, \
PapermillHandler getRecipeFromNotebook
from recipes.python_recipe import PythonRecipe, PythonHandler from .python_recipe import PythonRecipe, PythonHandler

View File

@ -11,21 +11,21 @@ import sys
from typing import Any, Tuple, Dict from typing import Any, Tuple, Dict
from core.base_recipe import BaseRecipe from meow_base.core.base_recipe import BaseRecipe
from core.base_handler import BaseHandler from meow_base.core.base_handler import BaseHandler
from core.correctness.meow import valid_event from meow_base.core.correctness.meow import valid_event
from core.correctness.validation import check_type, valid_string, \ from meow_base.core.correctness.validation import check_type, valid_string, \
valid_dict, valid_path, valid_dir_path valid_dict, valid_path, valid_dir_path, valid_existing_file_path
from core.correctness.vars import VALID_VARIABLE_NAME_CHARS, PYTHON_FUNC, \ from meow_base.core.correctness.vars import VALID_VARIABLE_NAME_CHARS, PYTHON_FUNC, \
DEBUG_INFO, EVENT_TYPE_WATCHDOG, JOB_HASH, DEFAULT_JOB_QUEUE_DIR, \ DEBUG_INFO, EVENT_TYPE_WATCHDOG, JOB_HASH, DEFAULT_JOB_QUEUE_DIR, \
EVENT_PATH, JOB_TYPE_PAPERMILL, WATCHDOG_HASH, JOB_PARAMETERS, \ EVENT_PATH, JOB_TYPE_PAPERMILL, WATCHDOG_HASH, JOB_PARAMETERS, \
JOB_ID, WATCHDOG_BASE, META_FILE, \ JOB_ID, WATCHDOG_BASE, META_FILE, \
PARAMS_FILE, JOB_STATUS, STATUS_QUEUED, EVENT_RULE, EVENT_TYPE, \ PARAMS_FILE, JOB_STATUS, STATUS_QUEUED, EVENT_RULE, EVENT_TYPE, \
EVENT_RULE, get_base_file EVENT_RULE, get_base_file
from functionality.debug import setup_debugging, print_debug from meow_base.functionality.debug import setup_debugging, print_debug
from functionality.file_io import make_dir, read_notebook, write_notebook, \ from meow_base.functionality.file_io import make_dir, read_notebook, write_notebook, \
write_yaml write_yaml
from functionality.meow import create_job, replace_keywords from meow_base.functionality.meow import create_job, replace_keywords
class JupyterNotebookRecipe(BaseRecipe): class JupyterNotebookRecipe(BaseRecipe):
@ -182,20 +182,37 @@ class PapermillHandler(BaseHandler):
# Send job directory, as actual definitons will be read from within it # Send job directory, as actual definitons will be read from within it
self.to_runner.send(job_dir) self.to_runner.send(job_dir)
#TODO test me
def getRecipeFromNotebook(name:str, notebook_filename:str,
parameters:Dict[str,Any]={}, requirements:Dict[str,Any]={}
)->JupyterNotebookRecipe:
valid_existing_file_path(notebook_filename, extension=".ipynb")
check_type(name, str, hint="getRecipeFromNotebook.name")
notebook_code = read_notebook(notebook_filename)
return JupyterNotebookRecipe(
name,
notebook_code,
parameters=parameters,
requirements=requirements,
source=notebook_filename
)
# Papermill job execution code, to be run within the conductor # Papermill job execution code, to be run within the conductor
def papermill_job_func(job_dir): def papermill_job_func(job_dir):
# Requires own imports as will be run in its own execution environment # Requires own imports as will be run in its own execution environment
import os import os
import papermill import papermill
from datetime import datetime from datetime import datetime
from core.correctness.vars import JOB_EVENT, JOB_ID, \ from meow_base.core.correctness.vars import JOB_EVENT, JOB_ID, \
EVENT_PATH, META_FILE, PARAMS_FILE, \ EVENT_PATH, META_FILE, PARAMS_FILE, \
JOB_STATUS, JOB_HASH, SHA256, STATUS_SKIPPED, JOB_END_TIME, \ JOB_STATUS, JOB_HASH, SHA256, STATUS_SKIPPED, JOB_END_TIME, \
JOB_ERROR, STATUS_FAILED, get_job_file, \ JOB_ERROR, STATUS_FAILED, get_job_file, \
get_result_file get_result_file
from functionality.file_io import read_yaml, write_notebook, write_yaml from meow_base.functionality.file_io import read_yaml, write_notebook, write_yaml
from functionality.hashing import get_file_hash from meow_base.functionality.hashing import get_file_hash
from functionality.parameterisation import parameterize_jupyter_notebook from meow_base.functionality.parameterisation import parameterize_jupyter_notebook
# Identify job files # Identify job files

View File

@ -10,21 +10,21 @@ import sys
from typing import Any, Tuple, Dict, List from typing import Any, Tuple, Dict, List
from core.base_recipe import BaseRecipe from meow_base.core.base_recipe import BaseRecipe
from core.base_handler import BaseHandler from meow_base.core.base_handler import BaseHandler
from core.correctness.meow import valid_event from meow_base.core.correctness.meow import valid_event
from core.correctness.validation import check_script, valid_string, \ from meow_base.core.correctness.validation import check_script, valid_string, \
valid_dict, valid_dir_path valid_dict, valid_dir_path
from core.correctness.vars import VALID_VARIABLE_NAME_CHARS, PYTHON_FUNC, \ from meow_base.core.correctness.vars import VALID_VARIABLE_NAME_CHARS, PYTHON_FUNC, \
DEBUG_INFO, EVENT_TYPE_WATCHDOG, JOB_HASH, DEFAULT_JOB_QUEUE_DIR, \ DEBUG_INFO, EVENT_TYPE_WATCHDOG, JOB_HASH, DEFAULT_JOB_QUEUE_DIR, \
EVENT_RULE, EVENT_PATH, JOB_TYPE_PYTHON, WATCHDOG_HASH, JOB_PARAMETERS, \ EVENT_RULE, EVENT_PATH, JOB_TYPE_PYTHON, WATCHDOG_HASH, JOB_PARAMETERS, \
JOB_ID, WATCHDOG_BASE, META_FILE, \ JOB_ID, WATCHDOG_BASE, META_FILE, \
PARAMS_FILE, JOB_STATUS, STATUS_QUEUED, EVENT_TYPE, EVENT_RULE, \ PARAMS_FILE, JOB_STATUS, STATUS_QUEUED, EVENT_TYPE, EVENT_RULE, \
get_base_file get_base_file
from functionality.debug import setup_debugging, print_debug from meow_base.functionality.debug import setup_debugging, print_debug
from functionality.file_io import make_dir, read_file_lines, write_file, \ from meow_base.functionality.file_io import make_dir, read_file_lines, write_file, \
write_yaml, lines_to_string write_yaml, lines_to_string
from functionality.meow import create_job, replace_keywords from meow_base.functionality.meow import create_job, replace_keywords
class PythonRecipe(BaseRecipe): class PythonRecipe(BaseRecipe):
@ -180,14 +180,14 @@ def python_job_func(job_dir):
import os import os
from datetime import datetime from datetime import datetime
from io import StringIO from io import StringIO
from core.correctness.vars import JOB_EVENT, JOB_ID, \ from meow_base.core.correctness.vars import JOB_EVENT, JOB_ID, \
EVENT_PATH, META_FILE, PARAMS_FILE, \ EVENT_PATH, META_FILE, PARAMS_FILE, \
JOB_STATUS, JOB_HASH, SHA256, STATUS_SKIPPED, JOB_END_TIME, \ JOB_STATUS, JOB_HASH, SHA256, STATUS_SKIPPED, JOB_END_TIME, \
JOB_ERROR, STATUS_FAILED, get_base_file, \ JOB_ERROR, STATUS_FAILED, get_base_file, \
get_job_file, get_result_file get_job_file, get_result_file
from functionality.file_io import read_yaml, write_yaml from meow_base.functionality.file_io import read_yaml, write_yaml
from functionality.hashing import get_file_hash from meow_base.functionality.hashing import get_file_hash
from functionality.parameterisation import parameterize_python_script from meow_base.functionality.parameterisation import parameterize_python_script
# Identify job files # Identify job files
meta_file = os.path.join(job_dir, META_FILE) meta_file = os.path.join(job_dir, META_FILE)

View File

@ -1,3 +1,3 @@
from rules.file_event_jupyter_notebook_rule import FileEventJupyterNotebookRule from .file_event_jupyter_notebook_rule import FileEventJupyterNotebookRule
from rules.file_event_python_rule import FileEventPythonRule from .file_event_python_rule import FileEventPythonRule

View File

@ -6,10 +6,10 @@ and JupyterNotebookRecipe.
Author(s): David Marchant Author(s): David Marchant
""" """
from core.base_rule import BaseRule from meow_base.core.base_rule import BaseRule
from core.correctness.validation import check_type from meow_base.core.correctness.validation import check_type
from patterns.file_event_pattern import FileEventPattern from meow_base.patterns.file_event_pattern import FileEventPattern
from recipes.jupyter_notebook_recipe import JupyterNotebookRecipe from meow_base.recipes.jupyter_notebook_recipe import JupyterNotebookRecipe
# TODO potentailly remove this and just invoke BaseRule directly, as does not # TODO potentailly remove this and just invoke BaseRule directly, as does not
# add any functionality other than some validation. # add any functionality other than some validation.

View File

@ -6,10 +6,10 @@ and PythonRecipe.
Author(s): David Marchant Author(s): David Marchant
""" """
from core.base_rule import BaseRule from meow_base.core.base_rule import BaseRule
from core.correctness.validation import check_type from meow_base.core.correctness.validation import check_type
from patterns.file_event_pattern import FileEventPattern from meow_base.patterns.file_event_pattern import FileEventPattern
from recipes.python_recipe import PythonRecipe from meow_base.recipes.python_recipe import PythonRecipe
# TODO potentailly remove this and just invoke BaseRule directly, as does not # TODO potentailly remove this and just invoke BaseRule directly, as does not
# add any functionality other than some validation. # add any functionality other than some validation.

View File

@ -7,10 +7,10 @@ import os
from distutils.dir_util import copy_tree from distutils.dir_util import copy_tree
from core.correctness.vars import DEFAULT_JOB_OUTPUT_DIR, DEFAULT_JOB_QUEUE_DIR from meow_base.core.correctness.vars import DEFAULT_JOB_OUTPUT_DIR, DEFAULT_JOB_QUEUE_DIR
from functionality.file_io import make_dir, rmtree from meow_base.functionality.file_io import make_dir, rmtree
from patterns import FileEventPattern from meow_base.patterns.file_event_pattern import FileEventPattern
from recipes import JupyterNotebookRecipe from meow_base.recipes.jupyter_notebook_recipe import JupyterNotebookRecipe
# testing # testing
TEST_DIR = "test_files" TEST_DIR = "test_files"

View File

@ -3,14 +3,14 @@ import unittest
from typing import Any, Union, Tuple, Dict from typing import Any, Union, Tuple, Dict
from core.base_conductor import BaseConductor from meow_base.core.base_conductor import BaseConductor
from core.base_handler import BaseHandler from meow_base.core.base_handler import BaseHandler
from core.base_monitor import BaseMonitor from meow_base.core.base_monitor import BaseMonitor
from core.base_pattern import BasePattern from meow_base.core.base_pattern import BasePattern
from core.base_recipe import BaseRecipe from meow_base.core.base_recipe import BaseRecipe
from core.base_rule import BaseRule from meow_base.core.base_rule import BaseRule
from core.correctness.vars import SWEEP_STOP, SWEEP_JUMP, SWEEP_START from meow_base.core.correctness.vars import SWEEP_STOP, SWEEP_JUMP, SWEEP_START
from patterns import FileEventPattern from meow_base.patterns.file_event_pattern import FileEventPattern
from shared import setup, teardown, valid_pattern_one, valid_recipe_one from shared import setup, teardown, valid_pattern_one, valid_recipe_one

View File

@ -5,21 +5,21 @@ import unittest
from datetime import datetime from datetime import datetime
from typing import Dict from typing import Dict
from core.correctness.vars import JOB_TYPE_PYTHON, SHA256, JOB_PARAMETERS, \ from meow_base.core.correctness.vars import JOB_TYPE_PYTHON, SHA256, JOB_PARAMETERS, \
JOB_HASH, PYTHON_FUNC, JOB_ID, BACKUP_JOB_ERROR_FILE, JOB_EVENT, \ JOB_HASH, PYTHON_FUNC, JOB_ID, BACKUP_JOB_ERROR_FILE, JOB_EVENT, \
META_FILE, PARAMS_FILE, JOB_STATUS, JOB_ERROR, JOB_TYPE, JOB_PATTERN, \ META_FILE, PARAMS_FILE, JOB_STATUS, JOB_ERROR, JOB_TYPE, JOB_PATTERN, \
STATUS_DONE, JOB_TYPE_PAPERMILL, JOB_RECIPE, JOB_RULE, JOB_CREATE_TIME, \ STATUS_DONE, JOB_TYPE_PAPERMILL, JOB_RECIPE, JOB_RULE, JOB_CREATE_TIME, \
JOB_REQUIREMENTS, EVENT_PATH, EVENT_RULE, EVENT_TYPE, \ JOB_REQUIREMENTS, EVENT_PATH, EVENT_RULE, EVENT_TYPE, \
EVENT_TYPE_WATCHDOG, get_base_file, get_result_file, get_job_file EVENT_TYPE_WATCHDOG, get_base_file, get_result_file, get_job_file
from conductors import LocalPythonConductor from meow_base.conductors import LocalPythonConductor
from functionality.file_io import read_file, read_yaml, write_file, \ from meow_base.functionality.file_io import read_file, read_yaml, write_file, \
write_notebook, write_yaml, lines_to_string, make_dir write_notebook, write_yaml, lines_to_string, make_dir
from functionality.hashing import get_file_hash from meow_base.functionality.hashing import get_file_hash
from functionality.meow import create_watchdog_event, create_job, create_rule from meow_base.functionality.meow import create_watchdog_event, create_job, create_rule
from patterns import FileEventPattern from meow_base.patterns.file_event_pattern import FileEventPattern
from recipes.jupyter_notebook_recipe import JupyterNotebookRecipe, \ from meow_base.recipes.jupyter_notebook_recipe import JupyterNotebookRecipe, \
papermill_job_func papermill_job_func
from recipes.python_recipe import PythonRecipe, python_job_func from meow_base.recipes.python_recipe import PythonRecipe, python_job_func
from shared import setup, teardown, TEST_MONITOR_BASE, APPENDING_NOTEBOOK, \ from shared import setup, teardown, TEST_MONITOR_BASE, APPENDING_NOTEBOOK, \
TEST_JOB_OUTPUT, TEST_JOB_QUEUE, COMPLETE_PYTHON_SCRIPT, \ TEST_JOB_OUTPUT, TEST_JOB_QUEUE, COMPLETE_PYTHON_SCRIPT, \
BAREBONES_PYTHON_SCRIPT, BAREBONES_NOTEBOOK BAREBONES_PYTHON_SCRIPT, BAREBONES_NOTEBOOK

View File

@ -11,34 +11,34 @@ from sys import prefix, base_prefix
from time import sleep from time import sleep
from typing import Dict from typing import Dict
from core.base_rule import BaseRule from meow_base.core.base_rule import BaseRule
from core.correctness.vars import CHAR_LOWERCASE, CHAR_UPPERCASE, \ from meow_base.core.correctness.vars import CHAR_LOWERCASE, CHAR_UPPERCASE, \
SHA256, EVENT_TYPE, EVENT_PATH, EVENT_TYPE_WATCHDOG, \ SHA256, EVENT_TYPE, EVENT_PATH, EVENT_TYPE_WATCHDOG, \
WATCHDOG_BASE, WATCHDOG_HASH, EVENT_RULE, JOB_PARAMETERS, JOB_HASH, \ WATCHDOG_BASE, WATCHDOG_HASH, EVENT_RULE, JOB_PARAMETERS, JOB_HASH, \
PYTHON_FUNC, JOB_ID, JOB_EVENT, \ PYTHON_FUNC, JOB_ID, JOB_EVENT, \
JOB_TYPE, JOB_PATTERN, JOB_RECIPE, JOB_RULE, JOB_STATUS, JOB_CREATE_TIME, \ JOB_TYPE, JOB_PATTERN, JOB_RECIPE, JOB_RULE, JOB_STATUS, JOB_CREATE_TIME, \
JOB_REQUIREMENTS, STATUS_QUEUED, JOB_TYPE_PAPERMILL JOB_REQUIREMENTS, STATUS_QUEUED, JOB_TYPE_PAPERMILL
from functionality.debug import setup_debugging from meow_base.functionality.debug import setup_debugging
from functionality.file_io import lines_to_string, make_dir, read_file, \ from meow_base.functionality.file_io import lines_to_string, make_dir, read_file, \
read_file_lines, read_notebook, read_yaml, rmtree, write_file, \ read_file_lines, read_notebook, read_yaml, rmtree, write_file, \
write_notebook, write_yaml write_notebook, write_yaml
from functionality.hashing import get_file_hash from meow_base.functionality.hashing import get_file_hash
from functionality.meow import create_event, create_job, create_rule, \ from meow_base.functionality.meow import create_event, create_job, create_rule, \
create_rules, create_watchdog_event, replace_keywords, \ create_rules, create_watchdog_event, replace_keywords, \
create_parameter_sweep, \ create_parameter_sweep, \
KEYWORD_BASE, KEYWORD_DIR, KEYWORD_EXTENSION, KEYWORD_FILENAME, \ KEYWORD_BASE, KEYWORD_DIR, KEYWORD_EXTENSION, KEYWORD_FILENAME, \
KEYWORD_JOB, KEYWORD_PATH, KEYWORD_PREFIX, KEYWORD_REL_DIR, \ KEYWORD_JOB, KEYWORD_PATH, KEYWORD_PREFIX, KEYWORD_REL_DIR, \
KEYWORD_REL_PATH KEYWORD_REL_PATH
from functionality.naming import _generate_id from meow_base.functionality.naming import _generate_id
from functionality.parameterisation import parameterize_jupyter_notebook, \ from meow_base.functionality.parameterisation import parameterize_jupyter_notebook, \
parameterize_python_script parameterize_python_script
from functionality.process_io import wait from meow_base.functionality.process_io import wait
from functionality.requirements import create_python_requirements, \ from meow_base.functionality.requirements import create_python_requirements, \
check_requirements, \ check_requirements, \
REQUIREMENT_PYTHON, REQ_PYTHON_ENVIRONMENT, REQ_PYTHON_MODULES, \ REQUIREMENT_PYTHON, REQ_PYTHON_ENVIRONMENT, REQ_PYTHON_MODULES, \
REQ_PYTHON_VERSION REQ_PYTHON_VERSION
from patterns import FileEventPattern from meow_base.patterns.file_event_pattern import FileEventPattern
from recipes import JupyterNotebookRecipe from meow_base.recipes.jupyter_notebook_recipe import JupyterNotebookRecipe
from shared import setup, teardown, valid_recipe_two, valid_recipe_one, \ from shared import setup, teardown, valid_recipe_two, valid_recipe_one, \
valid_pattern_one, valid_pattern_two, TEST_MONITOR_BASE, \ valid_pattern_one, valid_pattern_two, TEST_MONITOR_BASE, \
COMPLETE_NOTEBOOK, APPENDING_NOTEBOOK, COMPLETE_PYTHON_SCRIPT COMPLETE_NOTEBOOK, APPENDING_NOTEBOOK, COMPLETE_PYTHON_SCRIPT
@ -594,7 +594,7 @@ class MeowTests(unittest.TestCase):
self.assertEqual(len(rules), 0) self.assertEqual(len(rules), 0)
# Test that create_rules creates rules from patterns and recipes # Test that create_rules creates rules from meow_base.patterns and recipes
def testCreateRulesPatternsAndRecipesDicts(self)->None: def testCreateRulesPatternsAndRecipesDicts(self)->None:
patterns = { patterns = {
valid_pattern_one.name: valid_pattern_one, valid_pattern_one.name: valid_pattern_one,

View File

@ -5,13 +5,13 @@ import unittest
from multiprocessing import Pipe from multiprocessing import Pipe
from core.correctness.vars import FILE_CREATE_EVENT, EVENT_TYPE, \ from meow_base.core.correctness.vars import FILE_CREATE_EVENT, EVENT_TYPE, \
EVENT_RULE, WATCHDOG_BASE, EVENT_TYPE_WATCHDOG, EVENT_PATH, SWEEP_START, \ EVENT_RULE, WATCHDOG_BASE, EVENT_TYPE_WATCHDOG, EVENT_PATH, SWEEP_START, \
SWEEP_JUMP, SWEEP_STOP SWEEP_JUMP, SWEEP_STOP
from functionality.file_io import make_dir from meow_base.functionality.file_io import make_dir
from patterns.file_event_pattern import FileEventPattern, WatchdogMonitor, \ from meow_base.patterns.file_event_pattern import FileEventPattern, WatchdogMonitor, \
_DEFAULT_MASK _DEFAULT_MASK
from recipes import JupyterNotebookRecipe from meow_base.recipes.jupyter_notebook_recipe import JupyterNotebookRecipe
from shared import setup, teardown, BAREBONES_NOTEBOOK, TEST_MONITOR_BASE from shared import setup, teardown, BAREBONES_NOTEBOOK, TEST_MONITOR_BASE

View File

@ -6,23 +6,23 @@ import unittest
from multiprocessing import Pipe from multiprocessing import Pipe
from typing import Dict from typing import Dict
from core.correctness.meow import valid_job from meow_base.core.correctness.meow import valid_job
from core.correctness.vars import EVENT_TYPE, WATCHDOG_BASE, EVENT_RULE, \ from meow_base.core.correctness.vars import EVENT_TYPE, WATCHDOG_BASE, EVENT_RULE, \
EVENT_TYPE_WATCHDOG, EVENT_PATH, SHA256, WATCHDOG_HASH, JOB_ID, \ EVENT_TYPE_WATCHDOG, EVENT_PATH, SHA256, WATCHDOG_HASH, JOB_ID, \
JOB_TYPE_PYTHON, JOB_PARAMETERS, JOB_HASH, PYTHON_FUNC, JOB_STATUS, \ JOB_TYPE_PYTHON, JOB_PARAMETERS, JOB_HASH, PYTHON_FUNC, JOB_STATUS, \
META_FILE, JOB_ERROR, \ META_FILE, JOB_ERROR, \
PARAMS_FILE, SWEEP_STOP, SWEEP_JUMP, SWEEP_START, JOB_TYPE_PAPERMILL, \ PARAMS_FILE, SWEEP_STOP, SWEEP_JUMP, SWEEP_START, JOB_TYPE_PAPERMILL, \
get_base_file, get_job_file, get_result_file get_base_file, get_job_file, get_result_file
from functionality.file_io import lines_to_string, make_dir, read_yaml, \ from meow_base.functionality.file_io import lines_to_string, make_dir, read_yaml, \
write_file, write_notebook, write_yaml write_file, write_notebook, write_yaml
from functionality.hashing import get_file_hash from meow_base.functionality.hashing import get_file_hash
from functionality.meow import create_job, create_rules, create_rule, \ from meow_base.functionality.meow import create_job, create_rules, create_rule, \
create_watchdog_event create_watchdog_event
from patterns.file_event_pattern import FileEventPattern from meow_base.patterns.file_event_pattern import FileEventPattern
from recipes.jupyter_notebook_recipe import JupyterNotebookRecipe, \ from meow_base.recipes.jupyter_notebook_recipe import JupyterNotebookRecipe, \
PapermillHandler, papermill_job_func PapermillHandler, papermill_job_func
from recipes.python_recipe import PythonRecipe, PythonHandler, python_job_func from meow_base.recipes.python_recipe import PythonRecipe, PythonHandler, python_job_func
from rules import FileEventJupyterNotebookRule, FileEventPythonRule from meow_base.rules import FileEventPythonRule, FileEventJupyterNotebookRule
from shared import setup, teardown, BAREBONES_PYTHON_SCRIPT, \ from shared import setup, teardown, BAREBONES_PYTHON_SCRIPT, \
COMPLETE_PYTHON_SCRIPT, TEST_JOB_QUEUE, TEST_MONITOR_BASE, \ COMPLETE_PYTHON_SCRIPT, TEST_JOB_QUEUE, TEST_MONITOR_BASE, \
TEST_JOB_OUTPUT, BAREBONES_NOTEBOOK, APPENDING_NOTEBOOK, COMPLETE_NOTEBOOK TEST_JOB_OUTPUT, BAREBONES_NOTEBOOK, APPENDING_NOTEBOOK, COMPLETE_NOTEBOOK

View File

@ -1,9 +1,9 @@
import unittest import unittest
from patterns.file_event_pattern import FileEventPattern from meow_base.patterns.file_event_pattern import FileEventPattern
from recipes.jupyter_notebook_recipe import JupyterNotebookRecipe from meow_base.recipes.jupyter_notebook_recipe import JupyterNotebookRecipe
from rules.file_event_jupyter_notebook_rule import FileEventJupyterNotebookRule from meow_base.rules.file_event_jupyter_notebook_rule import FileEventJupyterNotebookRule
from shared import setup, teardown, BAREBONES_NOTEBOOK from shared import setup, teardown, BAREBONES_NOTEBOOK
class CorrectnessTests(unittest.TestCase): class CorrectnessTests(unittest.TestCase):

View File

@ -8,21 +8,21 @@ from random import shuffle
from shutil import copy from shutil import copy
from time import sleep from time import sleep
from core.base_conductor import BaseConductor from meow_base.core.base_conductor import BaseConductor
from core.base_handler import BaseHandler from meow_base.core.base_handler import BaseHandler
from core.base_monitor import BaseMonitor from meow_base.core.base_monitor import BaseMonitor
from conductors import LocalPythonConductor from meow_base.conductors import LocalPythonConductor
from core.correctness.vars import get_result_file, \ from meow_base.core.correctness.vars import get_result_file, \
JOB_TYPE_PAPERMILL, JOB_ERROR, META_FILE, JOB_TYPE_PYTHON, JOB_CREATE_TIME JOB_TYPE_PAPERMILL, JOB_ERROR, META_FILE, JOB_TYPE_PYTHON, JOB_CREATE_TIME
from core.runner import MeowRunner from meow_base.core.runner import MeowRunner
from functionality.file_io import make_dir, read_file, read_notebook, \ from meow_base.functionality.file_io import make_dir, read_file, read_notebook, \
read_yaml, write_file, lines_to_string read_yaml, write_file, lines_to_string
from functionality.meow import create_parameter_sweep from meow_base.functionality.meow import create_parameter_sweep
from functionality.requirements import create_python_requirements from meow_base.functionality.requirements import create_python_requirements
from patterns.file_event_pattern import WatchdogMonitor, FileEventPattern from meow_base.patterns.file_event_pattern import WatchdogMonitor, FileEventPattern
from recipes.jupyter_notebook_recipe import PapermillHandler, \ from meow_base.recipes.jupyter_notebook_recipe import PapermillHandler, \
JupyterNotebookRecipe JupyterNotebookRecipe
from recipes.python_recipe import PythonHandler, PythonRecipe from meow_base.recipes.python_recipe import PythonHandler, PythonRecipe
from shared import setup, teardown, backup_before_teardown, \ from shared import setup, teardown, backup_before_teardown, \
TEST_JOB_QUEUE, TEST_JOB_OUTPUT, TEST_MONITOR_BASE, MAKER_RECIPE, \ TEST_JOB_QUEUE, TEST_JOB_OUTPUT, TEST_MONITOR_BASE, MAKER_RECIPE, \
APPENDING_NOTEBOOK, COMPLETE_PYTHON_SCRIPT, TEST_DIR, FILTER_RECIPE, \ APPENDING_NOTEBOOK, COMPLETE_PYTHON_SCRIPT, TEST_DIR, FILTER_RECIPE, \
@ -916,10 +916,6 @@ class MeowTests(unittest.TestCase):
output = read_file(os.path.join(output_path)) output = read_file(os.path.join(output_path))
self.assertEqual(output, "12505000.0") self.assertEqual(output, "12505000.0")
def testSelfModifyingAnalysis(self)->None: def testSelfModifyingAnalysis(self)->None:
maker_pattern = FileEventPattern( maker_pattern = FileEventPattern(
"maker_pattern", "maker_pattern",

View File

@ -5,16 +5,16 @@ import os
from datetime import datetime from datetime import datetime
from typing import Any, Union from typing import Any, Union
from core.correctness.meow import valid_event, valid_job, valid_watchdog_event from meow_base.core.correctness.meow import valid_event, valid_job, valid_watchdog_event
from core.correctness.validation import check_type, check_implementation, \ from meow_base.core.correctness.validation import check_type, check_implementation, \
valid_string, valid_dict, valid_list, valid_existing_file_path, \ valid_string, valid_dict, valid_list, valid_existing_file_path, \
valid_dir_path, valid_non_existing_path, check_callable valid_dir_path, valid_non_existing_path, check_callable
from core.correctness.vars import VALID_NAME_CHARS, SHA256, EVENT_TYPE, \ from meow_base.core.correctness.vars import VALID_NAME_CHARS, SHA256, EVENT_TYPE, \
EVENT_PATH, JOB_TYPE, JOB_EVENT, JOB_ID, JOB_PATTERN, JOB_RECIPE, \ EVENT_PATH, JOB_TYPE, JOB_EVENT, JOB_ID, JOB_PATTERN, JOB_RECIPE, \
JOB_RULE, JOB_STATUS, JOB_CREATE_TIME, EVENT_RULE, WATCHDOG_BASE, \ JOB_RULE, JOB_STATUS, JOB_CREATE_TIME, EVENT_RULE, WATCHDOG_BASE, \
WATCHDOG_HASH WATCHDOG_HASH
from functionality.file_io import make_dir from meow_base.functionality.file_io import make_dir
from functionality.meow import create_rule from meow_base.functionality.meow import create_rule
from shared import setup, teardown, TEST_MONITOR_BASE, valid_pattern_one, \ from shared import setup, teardown, TEST_MONITOR_BASE, valid_pattern_one, \
valid_recipe_one valid_recipe_one