vfWorks 0.0.1.dev5__tar.gz → 0.0.2b1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/PKG-INFO +1 -1
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/pyproject.toml +1 -1
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfWorks.egg-info/PKG-INFO +1 -1
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/metamodels/monitors.py +20 -15
- vfworks-0.0.2b1/vfworks/metamodels/process.py +103 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/metamodels/validity_frame.py +181 -3
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/package/PackageManager.py +538 -371
- vfworks-0.0.1.dev5/vfworks/metamodels/process.py +0 -26
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/LICENSE +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/README.md +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/setup.cfg +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/setup.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfWorks.egg-info/SOURCES.txt +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfWorks.egg-info/dependency_links.txt +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfWorks.egg-info/entry_points.txt +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfWorks.egg-info/requires.txt +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfWorks.egg-info/top_level.txt +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/DSLs/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/DSLs/specificationModel/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/DSLs/specificationModel/grammar/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/DSLs/specificationModel/parser/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/DSLs/specificationModel/parser/parser.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/DSLs/specificationModel/templates/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/__main__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/clientLibraries/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/clientLibraries/vfclpy/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/clientLibraries/vfclpy/data_digest/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/clientLibraries/vfclpy/data_digest/digest.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/clientLibraries/vfclpy/data_forwarders/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/clientLibraries/vfclpy/data_forwarders/experiment.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/clientLibraries/vfclpy/data_platform.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/clientLibraries/vfclpy/probe.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/commands/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/commands/version.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/logging/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/logging/logger.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/metamodels/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/metamodels/common.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/metamodels/experiment.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/metamodels/knowledge_graph.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/metamodels/model_structure.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/metamodels/properties.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/metamodels/specification.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/metamodels/standard.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/metamodels/torch_representation.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/package/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/transformations/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/transformations/transformations.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/utils/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/utils/auxiliary.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/utils/constants.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/utils/data/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/utils/data/dataLoader.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/utils/model/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/utils/model/modelLoader.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/workflows/__init__.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/workflows/executer.py +0 -0
- {vfworks-0.0.1.dev5 → vfworks-0.0.2b1}/vfworks/workflows/tasks.py +0 -0
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
# * vfWorks can not be copied and/or distributed without the express
|
|
7
7
|
# * permission of Bert Van Acker
|
|
8
8
|
# **************************************************************************************
|
|
9
|
-
from vfworks.metamodels.common import *
|
|
10
|
-
from vfworks.utils.constants import *
|
|
11
|
-
import importlib.util
|
|
12
|
-
import os
|
|
13
|
-
from pathlib import Path
|
|
9
|
+
from vfworks.metamodels.common import *
|
|
10
|
+
from vfworks.utils.constants import *
|
|
11
|
+
import importlib.util
|
|
12
|
+
import os
|
|
13
|
+
from pathlib import Path
|
|
14
14
|
|
|
15
15
|
class Monitor(baseElement):
|
|
16
16
|
|
|
@@ -46,6 +46,11 @@ class Monitor(baseElement):
|
|
|
46
46
|
"""Setup the monitor, including loading any custom validation hooks."""
|
|
47
47
|
self._load_custom_validation_hook(packageLocation=packageLocation)
|
|
48
48
|
|
|
49
|
+
def set_valid(self):
|
|
50
|
+
for observe in self.observes:
|
|
51
|
+
self.spec_status[observe.feature] = StatusType.VALID
|
|
52
|
+
self._status = StatusType.VALID
|
|
53
|
+
|
|
49
54
|
@property
|
|
50
55
|
def packageName(self):
|
|
51
56
|
return self._packageName
|
|
@@ -169,16 +174,16 @@ class Monitor(baseElement):
|
|
|
169
174
|
|
|
170
175
|
return global_is_valid
|
|
171
176
|
|
|
172
|
-
def _load_custom_validation_hook(self, packageLocation=None):
|
|
173
|
-
"""Private helper to locate and bind custom vector validation scripts."""
|
|
174
|
-
package_root = Path(os.getcwd()) if packageLocation is None else Path(packageLocation)
|
|
175
|
-
custom_script_path = package_root / "Resources" / "monitors" / f"{self._custom_code_file}"
|
|
176
|
-
|
|
177
|
-
# Check if the user wrote a custom plugin matching this monitor type
|
|
178
|
-
if custom_script_path.exists():
|
|
179
|
-
try:
|
|
180
|
-
# Load the file dynamically as a Python module
|
|
181
|
-
spec = importlib.util.spec_from_file_location(self.name, custom_script_path)
|
|
177
|
+
def _load_custom_validation_hook(self, packageLocation=None):
|
|
178
|
+
"""Private helper to locate and bind custom vector validation scripts."""
|
|
179
|
+
package_root = Path(os.getcwd()) if packageLocation is None else Path(packageLocation)
|
|
180
|
+
custom_script_path = package_root / "Resources" / "monitors" / f"{self._custom_code_file}"
|
|
181
|
+
|
|
182
|
+
# Check if the user wrote a custom plugin matching this monitor type
|
|
183
|
+
if custom_script_path.exists():
|
|
184
|
+
try:
|
|
185
|
+
# Load the file dynamically as a Python module
|
|
186
|
+
spec = importlib.util.spec_from_file_location(self.name, custom_script_path)
|
|
182
187
|
custom_module = importlib.util.module_from_spec(spec)
|
|
183
188
|
spec.loader.exec_module(custom_module)
|
|
184
189
|
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#***************************************************************************************
|
|
2
|
+
# * Copyright (C) 2024-present Bert Van Acker (UAntwerpen) <Bert.VanAcker@uantwerpen.be>
|
|
3
|
+
# *
|
|
4
|
+
# * This file is part of the vfWorks project.
|
|
5
|
+
# *
|
|
6
|
+
# * vfWorks can not be copied and/or distributed without the express
|
|
7
|
+
# * permission of Bert Van Acker
|
|
8
|
+
# **************************************************************************************
|
|
9
|
+
from vfworks.metamodels.common import *
|
|
10
|
+
from vfworks.utils.constants import *
|
|
11
|
+
import importlib.util
|
|
12
|
+
import os
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
class Process(baseElement):
|
|
16
|
+
|
|
17
|
+
def __init__(self, name='tbd', description='tbd', verbose=False):
|
|
18
|
+
super().__init__(name=name, description=description, verbose=verbose)
|
|
19
|
+
|
|
20
|
+
self._tasks = []
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def tasks(self):
|
|
24
|
+
return self._tasks
|
|
25
|
+
|
|
26
|
+
@tasks.setter
|
|
27
|
+
def tasks(self, task_list):
|
|
28
|
+
self._tasks = task_list
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Task(baseElement):
|
|
33
|
+
|
|
34
|
+
def __init__(self, name='tbd', description='tbd',reference="Processes/train.py", verbose=False):
|
|
35
|
+
super().__init__(name=name, description=description, verbose=verbose)
|
|
36
|
+
|
|
37
|
+
self._input_artefacts = []
|
|
38
|
+
self._output_artefacts = []
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def input_artefacts(self):
|
|
42
|
+
return self._input_artefacts
|
|
43
|
+
|
|
44
|
+
@input_artefacts.setter
|
|
45
|
+
def input_artefacts(self, artefact_list):
|
|
46
|
+
self._input_artefacts = artefact_list
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def output_artefacts(self):
|
|
50
|
+
return self._output_artefacts
|
|
51
|
+
|
|
52
|
+
@output_artefacts.setter
|
|
53
|
+
def output_artefacts(self, artefact_list):
|
|
54
|
+
self._output_artefacts = artefact_list
|
|
55
|
+
|
|
56
|
+
def execute(self):
|
|
57
|
+
# Placeholder for task execution logic
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
def _load_custom_task_executor(self, reference):
|
|
61
|
+
"""Private helper to locate and bind custom vector validation scripts."""
|
|
62
|
+
package_root = Path(os.getcwd()) if packageLocation is None else Path(packageLocation)
|
|
63
|
+
custom_script_path = package_root / "Resources" / "monitors" / f"{self._custom_code_file}"
|
|
64
|
+
|
|
65
|
+
# Check if the user wrote a custom plugin matching this monitor type
|
|
66
|
+
if custom_script_path.exists():
|
|
67
|
+
try:
|
|
68
|
+
# Load the file dynamically as a Python module
|
|
69
|
+
spec = importlib.util.spec_from_file_location(self.name, custom_script_path)
|
|
70
|
+
custom_module = importlib.util.module_from_spec(spec)
|
|
71
|
+
spec.loader.exec_module(custom_module)
|
|
72
|
+
|
|
73
|
+
# Look for our standardized function name contract
|
|
74
|
+
if hasattr(custom_module, self.name):
|
|
75
|
+
self.execute = getattr(custom_module, self.name)
|
|
76
|
+
print(f"Successfully bound custom execution function for '{self.name}'")
|
|
77
|
+
else:
|
|
78
|
+
print(
|
|
79
|
+
f"Found custom script '{self._custom_code_file}.py', but it is missing '{self.name}'. "
|
|
80
|
+
f"Falling back to default built-in validation rules.",
|
|
81
|
+
level="warning"
|
|
82
|
+
)
|
|
83
|
+
except Exception as e:
|
|
84
|
+
print(f"Failed to compile custom monitor plugin '{self.name}': {str(e)}")
|
|
85
|
+
else:
|
|
86
|
+
# No custom script found; perfectly fine, it will use default built-in value.validate_point rules
|
|
87
|
+
print(f"No custom override found for '{self._custom_code_file}'. Running baseline configurations.")
|
|
88
|
+
|
|
89
|
+
class Artefact(baseElement):
|
|
90
|
+
|
|
91
|
+
def __init__(self, name='tbd', description='tbd',type='tbd',reference='tbd', verbose=False):
|
|
92
|
+
super().__init__(name=name, description=description, verbose=verbose)
|
|
93
|
+
|
|
94
|
+
self._type = type
|
|
95
|
+
self._reference = reference
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def reference(self):
|
|
99
|
+
return self._reference
|
|
100
|
+
|
|
101
|
+
@reference.setter
|
|
102
|
+
def reference(self,ref):
|
|
103
|
+
self._reference = ref
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import os
|
|
10
10
|
import json
|
|
11
11
|
import logging
|
|
12
|
+
import re
|
|
12
13
|
from pathlib import Path
|
|
13
14
|
from vfworks.package.PackageManager import PackageManager
|
|
14
15
|
from vfworks.metamodels.knowledge_graph import KnowledgeGraph
|
|
@@ -18,7 +19,8 @@ from vfworks.metamodels.specification import *
|
|
|
18
19
|
from vfworks.metamodels.experiment import *
|
|
19
20
|
from vfworks.metamodels.properties import *
|
|
20
21
|
from vfworks.metamodels.common import *
|
|
21
|
-
from vfworks.
|
|
22
|
+
from vfworks.metamodels.process import *
|
|
23
|
+
from vfworks.utils.constants import StatusType, MonitorTime
|
|
22
24
|
from vfworks.logging.logger import *
|
|
23
25
|
from vfworks.utils.model.modelLoader import *
|
|
24
26
|
import networkx as nx
|
|
@@ -26,7 +28,7 @@ import matplotlib.pyplot as plt
|
|
|
26
28
|
from termcolor import colored
|
|
27
29
|
|
|
28
30
|
class ValidityFrame(baseElement):
|
|
29
|
-
def __init__(self, name='tbd',description='tbd',config=None,loadExistingVF=False,VFPackage=None, location=None,verbose=False):
|
|
31
|
+
def __init__(self, name='tbd',description='tbd',config=None,loadExistingVF=False,VFPackage=None, location=None,verbose=False,unzipDirectory=None):
|
|
30
32
|
super().__init__(name=name, description=description, verbose=verbose)
|
|
31
33
|
|
|
32
34
|
# VF_BLDC HIGH-LEVEL STRUCTURE
|
|
@@ -37,7 +39,12 @@ class ValidityFrame(baseElement):
|
|
|
37
39
|
self._model_loader = ModelLoader(name="VF_model_loader", validityFrame=self)
|
|
38
40
|
|
|
39
41
|
# PACKAGE AND LOGGER
|
|
40
|
-
|
|
42
|
+
# VFPackage can be a package directory or a zipped package (.vf), which is unzipped to a working copy
|
|
43
|
+
self._log_handler = None
|
|
44
|
+
self._package_manager = PackageManager(verbose=verbose, packageName=VFPackage, packageLocation=location, unzipDirectory=unzipDirectory)
|
|
45
|
+
archive = self._package_manager.archive
|
|
46
|
+
if loadExistingVF and archive is not None and not archive.is_file():
|
|
47
|
+
raise FileNotFoundError(f"Zipped validity frame package {archive} does not exist!")
|
|
41
48
|
if config is None:
|
|
42
49
|
self.config = self._package_manager.init_config()
|
|
43
50
|
else:
|
|
@@ -239,6 +246,7 @@ class ValidityFrame(baseElement):
|
|
|
239
246
|
file_handler = logging.FileHandler(Path("..") / log_file) #LOAD FROM FOLDER LEVEL (e.g. in processes)
|
|
240
247
|
file_handler.setFormatter(formatter)
|
|
241
248
|
logger.addHandler(file_handler)
|
|
249
|
+
self._log_handler = file_handler
|
|
242
250
|
else:
|
|
243
251
|
console_handler = logging.StreamHandler()
|
|
244
252
|
console_handler.setFormatter(formatter)
|
|
@@ -387,6 +395,132 @@ class ValidityFrame(baseElement):
|
|
|
387
395
|
with open(file_name, 'w') as f:
|
|
388
396
|
json.dump(graph_dict, f)
|
|
389
397
|
|
|
398
|
+
def architecture_graph(self):
|
|
399
|
+
"""
|
|
400
|
+
Build an architecture graph payload from the metadata and operational state.
|
|
401
|
+
"""
|
|
402
|
+
|
|
403
|
+
def humanize(name):
|
|
404
|
+
return re.sub(r'(?<!^)(?=[A-Z])', ' ', str(name)).strip()
|
|
405
|
+
|
|
406
|
+
def normalize(value):
|
|
407
|
+
return getattr(value, 'value', value)
|
|
408
|
+
|
|
409
|
+
model_structure = self.activeModelStructure
|
|
410
|
+
if model_structure is None and self.modelStructures:
|
|
411
|
+
model_structure = self.modelStructures[0]
|
|
412
|
+
|
|
413
|
+
if model_structure is None:
|
|
414
|
+
component = {
|
|
415
|
+
"id": self.GUID,
|
|
416
|
+
"name": self.name,
|
|
417
|
+
"inputs": [],
|
|
418
|
+
"outputs": [],
|
|
419
|
+
"ai_architecture": {
|
|
420
|
+
"pattern": "unknown",
|
|
421
|
+
"models": [],
|
|
422
|
+
"flow": []
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
else:
|
|
426
|
+
inputs = []
|
|
427
|
+
for inport in model_structure.inports:
|
|
428
|
+
input_entry = {
|
|
429
|
+
"id": f"input_{inport.name}",
|
|
430
|
+
"name": inport.name,
|
|
431
|
+
"datatype": normalize(inport.datatype),
|
|
432
|
+
"dimensions": None,
|
|
433
|
+
"shape": [],
|
|
434
|
+
"unit": None if normalize(inport.unit) in (None, "-", "UNIT_none") else normalize(inport.unit),
|
|
435
|
+
"description": inport.description
|
|
436
|
+
}
|
|
437
|
+
if "image" in inport.name.lower() or "image" in inport.description.lower():
|
|
438
|
+
input_entry["format"] = "image"
|
|
439
|
+
inputs.append(input_entry)
|
|
440
|
+
|
|
441
|
+
outputs = []
|
|
442
|
+
has_confidence_output = False
|
|
443
|
+
for outport in model_structure.outports:
|
|
444
|
+
output_entry = {
|
|
445
|
+
"id": f"output_{outport.name}",
|
|
446
|
+
"name": outport.name,
|
|
447
|
+
"datatype": normalize(outport.datatype),
|
|
448
|
+
"dimensions": None,
|
|
449
|
+
"shape": [],
|
|
450
|
+
"unit": None if normalize(outport.unit) in (None, "-", "UNIT_none") else normalize(outport.unit),
|
|
451
|
+
"description": outport.description
|
|
452
|
+
}
|
|
453
|
+
if outport.min != 0 or outport.max != 0:
|
|
454
|
+
output_entry["value_range"] = {"min": outport.min, "max": outport.max}
|
|
455
|
+
if outport.name.lower() == "confidence":
|
|
456
|
+
has_confidence_output = True
|
|
457
|
+
outputs.append(output_entry)
|
|
458
|
+
|
|
459
|
+
model_entry = {
|
|
460
|
+
"id": f"model_{model_structure.name}",
|
|
461
|
+
"name": humanize(model_structure.name),
|
|
462
|
+
"type": normalize(model_structure.modelType),
|
|
463
|
+
"reference": model_structure.modelRef
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
flow = []
|
|
467
|
+
for input_entry in inputs:
|
|
468
|
+
flow.append({"from": input_entry["id"], "to": model_entry["id"]})
|
|
469
|
+
for output_entry in outputs:
|
|
470
|
+
flow.append({"from": model_entry["id"], "to": output_entry["id"]})
|
|
471
|
+
|
|
472
|
+
component = {
|
|
473
|
+
"id": model_structure.name,
|
|
474
|
+
"name": humanize(model_structure.name),
|
|
475
|
+
"inputs": inputs,
|
|
476
|
+
"outputs": outputs,
|
|
477
|
+
"ai_architecture": {
|
|
478
|
+
"pattern": "single_model_with_confidence_output" if has_confidence_output else "single_model",
|
|
479
|
+
"models": [model_entry],
|
|
480
|
+
"flow": flow
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
monitors = []
|
|
485
|
+
default_target = model_structure.inports[0].name if model_structure and model_structure.inports else "model"
|
|
486
|
+
for monitor in self.runtime_monitors:
|
|
487
|
+
if monitor.type == MonitorTime.DATA_VALIDATION:
|
|
488
|
+
target = "dataset"
|
|
489
|
+
elif monitor.type == MonitorTime.MODEL_VALIDATION:
|
|
490
|
+
target = "model"
|
|
491
|
+
elif monitor.type == MonitorTime.RUN_TIME:
|
|
492
|
+
observed_features = [spec.feature for spec in (monitor.observes or [])]
|
|
493
|
+
if any("odd" in feature.lower() for feature in observed_features) or "odd" in monitor.name.lower() or "odd" in monitor.description.lower():
|
|
494
|
+
target = "environment"
|
|
495
|
+
else:
|
|
496
|
+
target = default_target
|
|
497
|
+
else:
|
|
498
|
+
target = default_target
|
|
499
|
+
|
|
500
|
+
monitors.append({
|
|
501
|
+
"name": monitor.name,
|
|
502
|
+
"target": target,
|
|
503
|
+
"description": monitor.description,
|
|
504
|
+
"observes": [spec.feature for spec in (monitor.observes or [])]
|
|
505
|
+
})
|
|
506
|
+
|
|
507
|
+
return {
|
|
508
|
+
"component": component,
|
|
509
|
+
"monitors": monitors
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
def export_architecture_json(self, file_name="architecture.json"):
|
|
513
|
+
"""
|
|
514
|
+
Export the architecture graph payload to a JSON file.
|
|
515
|
+
"""
|
|
516
|
+
architecture = self.architecture_graph()
|
|
517
|
+
output_path = Path(file_name)
|
|
518
|
+
if not output_path.is_absolute():
|
|
519
|
+
output_path = self.package_manager.package_root / output_path
|
|
520
|
+
|
|
521
|
+
with open(output_path, 'w', encoding='utf-8') as f:
|
|
522
|
+
json.dump(architecture, f, indent=2)
|
|
523
|
+
|
|
390
524
|
# ------------------------------------------------------------------------------------------------------------------
|
|
391
525
|
# IMPORT/EXPORT FUNCTIONS
|
|
392
526
|
# -----------------------------------------------------------------------------------------------------------------
|
|
@@ -396,6 +530,30 @@ class ValidityFrame(baseElement):
|
|
|
396
530
|
self._processes.object2json(package_root / "Processes" / "Processes.json")
|
|
397
531
|
self._experiments.object2json(package_root / "Experiments" / "Experiments.json")
|
|
398
532
|
self._operational.object2json(package_root / "Operational" / "Operational.json")
|
|
533
|
+
# keep the zipped package (.vf) in sync with its unzipped working copy
|
|
534
|
+
if packageName is None and self.package_manager.archive is not None:
|
|
535
|
+
self.package_manager.zip()
|
|
536
|
+
|
|
537
|
+
def zip(self, archive=None):
|
|
538
|
+
"""
|
|
539
|
+
Export the validity frame and zip its package into a .vf archive.
|
|
540
|
+
Defaults to the archive the validity frame was loaded from.
|
|
541
|
+
"""
|
|
542
|
+
self.export()
|
|
543
|
+
if archive is None and self.package_manager.archive is not None:
|
|
544
|
+
return self.package_manager.archive
|
|
545
|
+
return self.package_manager.zip(archive=archive)
|
|
546
|
+
|
|
547
|
+
def close(self):
|
|
548
|
+
"""
|
|
549
|
+
Release the log file and the unzipped working copy of a zipped package (.vf).
|
|
550
|
+
Changes made after the last export()/zip() are not written to the archive.
|
|
551
|
+
"""
|
|
552
|
+
if self._log_handler is not None:
|
|
553
|
+
self.logger.removeHandler(self._log_handler)
|
|
554
|
+
self._log_handler.close()
|
|
555
|
+
self._log_handler = None
|
|
556
|
+
self.package_manager.close()
|
|
399
557
|
|
|
400
558
|
|
|
401
559
|
class MetaData(baseElement):
|
|
@@ -639,6 +797,26 @@ class Processes(baseElement):
|
|
|
639
797
|
with open(fileName, 'w', encoding='utf-8') as f:
|
|
640
798
|
f.write(data)
|
|
641
799
|
|
|
800
|
+
def json2object(self, fileName):
|
|
801
|
+
"""
|
|
802
|
+
Function to generate object from a json file
|
|
803
|
+
"""
|
|
804
|
+
# --- read stored requirements ---
|
|
805
|
+
available = False
|
|
806
|
+
try:
|
|
807
|
+
f = open(fileName)
|
|
808
|
+
data = json.load(f)
|
|
809
|
+
available = True
|
|
810
|
+
except:
|
|
811
|
+
print(colored('ERROR: ', 'red'), colored('Stored operational data cannot be read!', 'black'))
|
|
812
|
+
|
|
813
|
+
if available:
|
|
814
|
+
for process in data["_processes"]:
|
|
815
|
+
_process = Process(name=process["_name"], description=process["_description"], processType=process["_processType"], custom_code_file=process["_custom_code_file"])
|
|
816
|
+
_process.GUID = process["_GUID"]
|
|
817
|
+
_process.timestamp = process["_timestamp"]
|
|
818
|
+
self.addProcess(_process)
|
|
819
|
+
|
|
642
820
|
class Experiments(baseElement):
|
|
643
821
|
def __init__(self, name='tbd',description='tbd',experiments=None,verbose=False):
|
|
644
822
|
super().__init__(name=name, description=description, verbose=verbose)
|