logs-py 2.9.5__py3-none-any.whl → 3.0.0__py3-none-any.whl
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.
Potentially problematic release.
This version of logs-py might be problematic. Click here for more details.
- LOGS/Auxiliary/DateTimeConverter.py +11 -1
- LOGS/Auxiliary/Exceptions.py +40 -4
- LOGS/Auxiliary/LOGSErrorResponse.py +4 -1
- LOGS/Auxiliary/MinimalModelGenerator.py +88 -28
- LOGS/Auxiliary/Tools.py +11 -0
- LOGS/Converter/Conversion.py +248 -0
- LOGS/Converter/Converter.py +96 -0
- LOGS/Converter/ConverterParameter.py +88 -0
- LOGS/Converter/ExportParamters.py +89 -0
- LOGS/Converter/__init__.py +13 -0
- LOGS/Entities/Bridge.py +6 -3
- LOGS/Entities/CustomField.py +98 -93
- LOGS/Entities/CustomFieldModels.py +57 -0
- LOGS/Entities/CustomFieldRelations.py +10 -0
- LOGS/Entities/CustomFieldRequestParameter.py +43 -15
- LOGS/Entities/CustomFieldValue.py +88 -0
- LOGS/Entities/CustomFieldValueConverter.py +66 -0
- LOGS/Entities/CustomType.py +187 -0
- LOGS/Entities/CustomTypeEntityType.py +11 -0
- LOGS/Entities/CustomTypeMinimal.py +8 -0
- LOGS/Entities/CustomTypeRelations.py +59 -0
- LOGS/Entities/CustomTypeRequestParameter.py +61 -0
- LOGS/Entities/CustomTypeSection.py +39 -0
- LOGS/Entities/CustomTypes.py +12 -0
- LOGS/Entities/DataSource.py +28 -14
- LOGS/Entities/Dataset.py +276 -138
- LOGS/Entities/DatasetCreator.py +23 -72
- LOGS/Entities/DatasetInfo.py +23 -2
- LOGS/Entities/DatasetModels.py +31 -0
- LOGS/Entities/DatasetRequestParameter.py +45 -32
- LOGS/Entities/Datatrack.py +74 -30
- LOGS/Entities/DatatrackFormattedTable.py +25 -0
- LOGS/Entities/DatatrackGeneric.py +34 -0
- LOGS/Entities/DatatrackImage.py +25 -0
- LOGS/Entities/DatatrackNumericArray.py +9 -39
- LOGS/Entities/DatatrackNumericMatrix.py +86 -0
- LOGS/Entities/DocumentRequestParameter.py +2 -2
- LOGS/Entities/EntitiesRequestParameter.py +2 -2
- LOGS/Entities/Experiment.py +3 -3
- LOGS/Entities/FileExcludePattern.py +8 -0
- LOGS/Entities/FormatFormat.py +22 -1
- LOGS/Entities/FormatFormatRequestParameter.py +2 -1
- LOGS/Entities/FormatFormats.py +1 -1
- LOGS/Entities/FormatMethod.py +2 -2
- LOGS/Entities/FormattedTable/DatatypeFormattedTable.py +135 -0
- LOGS/Entities/FormattedTable/DatatypeFormattedTableCell.py +108 -0
- LOGS/Entities/FormattedTable/DatatypeFormattedTableSettings.py +11 -0
- LOGS/Entities/FormattedTable/__init__.py +9 -0
- LOGS/Entities/ILiterarTypedEntity.py +19 -0
- LOGS/Entities/Instrument.py +3 -3
- LOGS/Entities/Inventories.py +12 -0
- LOGS/Entities/Inventory.py +95 -0
- LOGS/Entities/InventoryMinimal.py +20 -0
- LOGS/Entities/InventoryRelations.py +23 -0
- LOGS/Entities/InventoryRequestParameter.py +53 -0
- LOGS/Entities/LabNotebook.py +37 -0
- LOGS/Entities/LabNotebookEntry.py +50 -27
- LOGS/Entities/LabNotebookEntryContent/BasicAttribute.py +15 -0
- LOGS/Entities/LabNotebookEntryContent/EntityAttribute.py +85 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentBlockquote.py +13 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentBulletList.py +17 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentCallout.py +40 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentContentPlaceholderNode.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentConverter.py +207 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentDocument.py +8 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentEntity.py +13 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentEntityMention.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentHeading.py +33 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentHorizontalRule.py +12 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentItem.py +37 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentListItem.py +49 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentOrderedList.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentParagraph.py +13 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTable.py +17 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTableCell.py +40 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTableRow.py +8 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTaskList.py +17 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTaskListItem.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentText.py +33 -0
- LOGS/Entities/LabNotebookEntryContent/IEntryContentWithAttribute.py +23 -0
- LOGS/Entities/LabNotebookEntryContent/IEntryContentWithContent.py +38 -0
- LOGS/Entities/LabNotebookEntryContent/IEntryContentWithTextAttribute.py +16 -0
- LOGS/Entities/LabNotebookEntryContent/TextAttribute.py +46 -0
- LOGS/Entities/LabNotebookEntryContent/TextMarkAtributes.py +64 -0
- LOGS/Entities/LabNotebookEntryContent/TextMarkConverter.py +45 -0
- LOGS/Entities/LabNotebookEntryContent/TextMarks.py +71 -0
- LOGS/Entities/LabNotebookEntryContent/__init__.py +34 -0
- LOGS/Entities/LabNotebookEntryRequestParameter.py +2 -0
- LOGS/Entities/LabNotebookExperiment.py +52 -0
- LOGS/Entities/LabNotebookExperimentMinimal.py +8 -0
- LOGS/Entities/LabNotebookExperimentRequestParameter.py +49 -0
- LOGS/Entities/LabNotebookExperiments.py +16 -0
- LOGS/Entities/LabNotebookMinimal.py +19 -0
- LOGS/Entities/LabNotebookModels.py +14 -0
- LOGS/Entities/LabNotebookRequestParameter.py +43 -0
- LOGS/Entities/LabNotebooks.py +12 -0
- LOGS/Entities/Method.py +3 -3
- LOGS/Entities/ParserLog.py +4 -0
- LOGS/Entities/Person.py +2 -2
- LOGS/Entities/Project.py +7 -7
- LOGS/Entities/{ProjectUserPermission.py → ProjectPersonPermission.py} +14 -4
- LOGS/Entities/Role.py +3 -3
- LOGS/Entities/RunState.py +1 -0
- LOGS/Entities/Sample.py +36 -57
- LOGS/Entities/SampleRequestParameter.py +30 -15
- LOGS/Entities/Track.py +10 -6
- LOGS/Entities/TrackData.py +11 -0
- LOGS/Entities/TrackImage.py +21 -0
- LOGS/Entities/TrackImageData.py +20 -0
- LOGS/Entities/TrackMatrix.py +28 -0
- LOGS/Entities/TrackMatrixData.py +22 -0
- LOGS/Entities/TrackTable.py +21 -0
- LOGS/Entities/TrackTableData.py +22 -0
- LOGS/Entities/TrackXY.py +5 -1
- LOGS/Entities/TrackXYComplex.py +1 -1
- LOGS/Entities/__init__.py +26 -7
- LOGS/Entity/ConnectedEntity.py +39 -1
- LOGS/Entity/Entity.py +9 -14
- LOGS/Entity/SerializeableContent.py +127 -45
- LOGS/Interfaces/IHierarchyType.py +63 -0
- LOGS/Interfaces/IPermissionedEntity.py +29 -5
- LOGS/Interfaces/IProjectBased.py +1 -1
- LOGS/Interfaces/IRelatedEntity.py +3 -2
- LOGS/Interfaces/ITypedEntity.py +69 -12
- LOGS/Interfaces/IVersionedEntity.py +39 -0
- LOGS/LOGS.py +140 -48
- LOGS/LOGSConnection.py +52 -24
- LOGS/LOGSOptions.py +8 -0
- LOGS/Parameters/Color.py +92 -0
- LOGS/Parameters/ParameterBase.py +55 -0
- LOGS/Parameters/ParameterConverter.py +24 -0
- LOGS/Parameters/ParameterElement.py +99 -0
- LOGS/Parameters/ParameterList.py +52 -0
- LOGS/Parameters/ParameterTable.py +64 -0
- LOGS/Parameters/__init__.py +13 -0
- LOGS/__init__.py +1 -0
- {logs_py-2.9.5.dist-info → logs_py-3.0.0.dist-info}/METADATA +3 -2
- logs_py-3.0.0.dist-info/RECORD +263 -0
- {logs_py-2.9.5.dist-info → logs_py-3.0.0.dist-info}/WHEEL +1 -1
- LOGS/Entities/CustomFieldEnums.py +0 -25
- LOGS/Entities/DatasetType.py +0 -7
- LOGS/Entities/DatasetTypeMinimal.py +0 -8
- LOGS/Entities/SampleType.py +0 -34
- LOGS/Entities/SampleTypeMinimal.py +0 -8
- LOGS/Entities/SampleTypeRequestParameter.py +0 -8
- LOGS/Entities/SampleTypes.py +0 -12
- logs_py-2.9.5.dist-info/RECORD +0 -183
- {logs_py-2.9.5.dist-info → logs_py-3.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from LOGS.Entities.DatatrackNumericMatrix import DatatrackNumericMatrix
|
|
4
|
+
from LOGS.Entities.TrackData import TrackData
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TrackMatrixData(TrackData):
|
|
8
|
+
_matrix: Optional[DatatrackNumericMatrix] = None
|
|
9
|
+
|
|
10
|
+
def fetchFull(self):
|
|
11
|
+
if self.matrix:
|
|
12
|
+
self.matrix.fetchFull()
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def matrix(self) -> Optional[DatatrackNumericMatrix]:
|
|
16
|
+
return self._matrix
|
|
17
|
+
|
|
18
|
+
@matrix.setter
|
|
19
|
+
def matrix(self, value):
|
|
20
|
+
self._matrix = self.checkAndConvertNullable(
|
|
21
|
+
value, DatatrackNumericMatrix, "matrix"
|
|
22
|
+
)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from LOGS.Entities.Track import Track
|
|
4
|
+
from LOGS.Entities.TrackTableData import TrackTableData
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TrackTable(Track):
|
|
8
|
+
_datatracks: Optional[TrackTableData] = None
|
|
9
|
+
|
|
10
|
+
def _fetchData(self):
|
|
11
|
+
if self.datatracks:
|
|
12
|
+
if self.datatracks.table:
|
|
13
|
+
self.datatracks.table.fetchFull()
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def datatracks(self) -> Optional[TrackTableData]:
|
|
17
|
+
return self._datatracks
|
|
18
|
+
|
|
19
|
+
@datatracks.setter
|
|
20
|
+
def datatracks(self, value):
|
|
21
|
+
self._datatracks = self.checkAndConvertNullable(value, TrackTableData, "data")
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from LOGS.Entities.DatatrackFormattedTable import DatatrackFormattedTable
|
|
4
|
+
from LOGS.Entities.TrackData import TrackData
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TrackTableData(TrackData):
|
|
8
|
+
_table: Optional[DatatrackFormattedTable] = None
|
|
9
|
+
|
|
10
|
+
def fetchFull(self):
|
|
11
|
+
if self.table:
|
|
12
|
+
self.table.fetchFull()
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def table(self) -> Optional[DatatrackFormattedTable]:
|
|
16
|
+
return self._table
|
|
17
|
+
|
|
18
|
+
@table.setter
|
|
19
|
+
def table(self, value):
|
|
20
|
+
self._table = self.checkAndConvertNullable(
|
|
21
|
+
value, DatatrackFormattedTable, "matrix"
|
|
22
|
+
)
|
LOGS/Entities/TrackXY.py
CHANGED
|
@@ -10,8 +10,10 @@ class TrackXY(Track):
|
|
|
10
10
|
def _fetchData(self):
|
|
11
11
|
if self.datatracks:
|
|
12
12
|
if self.datatracks.x:
|
|
13
|
+
self.datatracks.x.cacheDir = self.cacheDir
|
|
13
14
|
self.datatracks.x.fetchFull()
|
|
14
15
|
if self.datatracks.y:
|
|
16
|
+
self.datatracks.y.cacheDir = self.cacheDir
|
|
15
17
|
self.datatracks.y.fetchFull()
|
|
16
18
|
|
|
17
19
|
def __iter__(self):
|
|
@@ -33,4 +35,6 @@ class TrackXY(Track):
|
|
|
33
35
|
|
|
34
36
|
@datatracks.setter
|
|
35
37
|
def datatracks(self, value):
|
|
36
|
-
self._datatracks = self.checkAndConvertNullable(
|
|
38
|
+
self._datatracks = self.checkAndConvertNullable(
|
|
39
|
+
value, TrackXYData, "datatracks"
|
|
40
|
+
)
|
LOGS/Entities/TrackXYComplex.py
CHANGED
LOGS/Entities/__init__.py
CHANGED
|
@@ -15,10 +15,14 @@ from .BridgeMinimal import *
|
|
|
15
15
|
from .BridgeRequestParameter import *
|
|
16
16
|
from .BridgeType import *
|
|
17
17
|
from .CustomField import *
|
|
18
|
-
from .
|
|
18
|
+
from .CustomFieldModels import *
|
|
19
19
|
from .CustomFieldRequestParameter import *
|
|
20
|
+
from .CustomFieldValue import *
|
|
20
21
|
from .CustomSchema import *
|
|
21
22
|
from .CustomSchemaSection import *
|
|
23
|
+
from .CustomType import *
|
|
24
|
+
from .CustomTypeMinimal import *
|
|
25
|
+
from .CustomTypeRequestParameter import *
|
|
22
26
|
from .Dataset import *
|
|
23
27
|
from .DatasetCreator import *
|
|
24
28
|
from .DatasetInfo import *
|
|
@@ -28,14 +32,15 @@ from .DatasetMinimal import *
|
|
|
28
32
|
from .DatasetRelations import *
|
|
29
33
|
from .DatasetRequestParameter import *
|
|
30
34
|
from .Datasets import *
|
|
31
|
-
from .DatasetType import *
|
|
32
|
-
from .DatasetTypeMinimal import *
|
|
33
35
|
from .DatasetUploadParameter import *
|
|
34
36
|
from .DataSource import *
|
|
35
37
|
from .DataSourceMinimal import *
|
|
36
38
|
from .DataSourceRequestParameter import *
|
|
37
39
|
from .Datatrack import *
|
|
40
|
+
from .DatatrackFormattedTable import *
|
|
41
|
+
from .DatatrackImage import *
|
|
38
42
|
from .DatatrackNumericArray import *
|
|
43
|
+
from .DatatrackNumericMatrix import *
|
|
39
44
|
from .Document import *
|
|
40
45
|
from .DocumentRelations import *
|
|
41
46
|
from .DocumentRequestParameter import *
|
|
@@ -63,10 +68,23 @@ from .Instrument import *
|
|
|
63
68
|
from .InstrumentMinimal import *
|
|
64
69
|
from .InstrumentRequestParameter import *
|
|
65
70
|
from .Instruments import *
|
|
71
|
+
from .Inventory import *
|
|
72
|
+
from .InventoryMinimal import *
|
|
73
|
+
from .InventoryRequestParameter import *
|
|
74
|
+
from .LabNotebook import *
|
|
66
75
|
from .LabNotebookEntries import *
|
|
67
|
-
from .
|
|
76
|
+
from .LabNotebookEntryContent import *
|
|
68
77
|
from .LabNotebookEntryMinimal import *
|
|
78
|
+
from .LabNotebookEntryRelations import *
|
|
69
79
|
from .LabNotebookEntryRequestParameter import *
|
|
80
|
+
from .LabNotebookExperiment import *
|
|
81
|
+
from .LabNotebookExperimentMinimal import *
|
|
82
|
+
from .LabNotebookExperimentRequestParameter import *
|
|
83
|
+
from .LabNotebookExperiments import *
|
|
84
|
+
from .LabNotebookMinimal import *
|
|
85
|
+
from .LabNotebookModels import *
|
|
86
|
+
from .LabNotebookRequestParameter import *
|
|
87
|
+
from .LabNotebooks import *
|
|
70
88
|
from .Method import *
|
|
71
89
|
from .MethodMinimal import *
|
|
72
90
|
from .MethodRequestParameter import *
|
|
@@ -94,11 +112,12 @@ from .SampleMinimal import *
|
|
|
94
112
|
from .SampleRelations import *
|
|
95
113
|
from .SampleRequestParameter import *
|
|
96
114
|
from .Samples import *
|
|
97
|
-
from .SampleType import *
|
|
98
|
-
from .SampleTypeMinimal import *
|
|
99
|
-
from .SampleTypeRequestParameter import *
|
|
100
115
|
from .Track import *
|
|
101
116
|
from .TrackData import *
|
|
117
|
+
from .TrackImage import *
|
|
118
|
+
from .TrackImageData import *
|
|
119
|
+
from .TrackMatrix import *
|
|
120
|
+
from .TrackMatrixData import *
|
|
102
121
|
from .TrackSettings import *
|
|
103
122
|
from .TrackXY import *
|
|
104
123
|
from .TrackXYComplex import *
|
LOGS/Entity/ConnectedEntity.py
CHANGED
|
@@ -9,7 +9,9 @@ class ConnectedEntity(SerializeableContent):
|
|
|
9
9
|
_connection: Optional[LOGSConnection]
|
|
10
10
|
_endpoint: Optional[List[str]] = None
|
|
11
11
|
_uiEndpoint: Optional[List[str]] = None
|
|
12
|
-
_noSerialize = ["connection"]
|
|
12
|
+
_noSerialize = ["connection", "cachePath", "cacheId", "cacheDir"]
|
|
13
|
+
_cacheDir: Optional[str] = None
|
|
14
|
+
_cacheId: str = cast(str, None)
|
|
13
15
|
|
|
14
16
|
def __init__(self, ref=None, connection: Optional[LOGSConnection] = None):
|
|
15
17
|
self._connection = connection
|
|
@@ -24,6 +26,24 @@ class ConnectedEntity(SerializeableContent):
|
|
|
24
26
|
raise EntityNotConnectedException(self)
|
|
25
27
|
return self._connection
|
|
26
28
|
|
|
29
|
+
def _getConnectionData(self):
|
|
30
|
+
if not self._endpoint:
|
|
31
|
+
raise NotImplementedError(
|
|
32
|
+
"Endpoint missing for of entity type %a."
|
|
33
|
+
% (
|
|
34
|
+
type(self).__name__
|
|
35
|
+
if type(self).__name__ != ConnectedEntity.__name__
|
|
36
|
+
else "unknown"
|
|
37
|
+
)
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
return self._getConnection(), self._endpoint
|
|
41
|
+
|
|
42
|
+
def clearCache(self):
|
|
43
|
+
raise NotImplementedError(
|
|
44
|
+
"Clearing cache of %a class is not implemented." % type(self).__name__
|
|
45
|
+
)
|
|
46
|
+
|
|
27
47
|
@property
|
|
28
48
|
def connection(self) -> Optional[LOGSConnection]:
|
|
29
49
|
return self._connection
|
|
@@ -43,3 +63,21 @@ class ConnectedEntity(SerializeableContent):
|
|
|
43
63
|
@property
|
|
44
64
|
def identifier(self):
|
|
45
65
|
return "%s" % (type(self).__name__)
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def cacheDir(self) -> Optional[str]:
|
|
69
|
+
return self._cacheDir
|
|
70
|
+
|
|
71
|
+
@cacheDir.setter
|
|
72
|
+
def cacheDir(self, value):
|
|
73
|
+
self._cacheDir = self.checkAndConvertNullable(value, str, "cacheDir")
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def cacheId(self) -> str:
|
|
77
|
+
if self._cacheId is None:
|
|
78
|
+
if not hasattr(self, "id"):
|
|
79
|
+
setattr(self, "id", self.generateID())
|
|
80
|
+
|
|
81
|
+
return f"{type(self).__name__}_{str(getattr(self, 'id'))}"
|
|
82
|
+
else:
|
|
83
|
+
return self._cacheId
|
LOGS/Entity/Entity.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Any, Optional, cast
|
|
2
2
|
|
|
3
|
-
from LOGS.Auxiliary import MinimalModelGenerator
|
|
3
|
+
from LOGS.Auxiliary import MinimalModelGenerator, Tools
|
|
4
4
|
from LOGS.Auxiliary.Constants import Constants
|
|
5
5
|
from LOGS.Auxiliary.Exceptions import (
|
|
6
6
|
EntityDeletingException,
|
|
@@ -32,24 +32,15 @@ class Entity(ConnectedEntity):
|
|
|
32
32
|
super().__init__(ref=ref, connection=connection)
|
|
33
33
|
|
|
34
34
|
def _getConnectionData(self):
|
|
35
|
-
|
|
36
|
-
raise NotImplementedError(
|
|
37
|
-
"Endpoint missing for of entity type %a."
|
|
38
|
-
% (
|
|
39
|
-
type(self).__name__
|
|
40
|
-
if type(self).__name__ != Entity.__name__
|
|
41
|
-
else "unknown"
|
|
42
|
-
)
|
|
43
|
-
)
|
|
35
|
+
(connection, endpoint) = super()._getConnectionData()
|
|
44
36
|
|
|
45
37
|
if not self.id:
|
|
46
38
|
raise EntityNotFoundException(self)
|
|
47
39
|
|
|
48
|
-
return
|
|
40
|
+
return connection, endpoint, self.id
|
|
49
41
|
|
|
50
42
|
def __str__(self):
|
|
51
|
-
|
|
52
|
-
return "<%s id:%s%s>" % (type(self).__name__, str(self.id), s)
|
|
43
|
+
return Tools.ObjectToString(self)
|
|
53
44
|
|
|
54
45
|
def getUIUrl(self) -> str:
|
|
55
46
|
if not self._uiEndpoint:
|
|
@@ -188,7 +179,11 @@ class Entity(ConnectedEntity):
|
|
|
188
179
|
|
|
189
180
|
@property
|
|
190
181
|
def identifier(self):
|
|
191
|
-
name =
|
|
182
|
+
name = (
|
|
183
|
+
f" '{getattr(self, 'name')}'"
|
|
184
|
+
if hasattr(self, "name") and getattr(self, "name")
|
|
185
|
+
else ""
|
|
186
|
+
)
|
|
192
187
|
return "%s(id:%s)%s" % (
|
|
193
188
|
type(self).__name__,
|
|
194
189
|
str(self.id),
|
|
@@ -2,7 +2,6 @@ import inspect
|
|
|
2
2
|
import json
|
|
3
3
|
import math
|
|
4
4
|
import random
|
|
5
|
-
from copy import deepcopy
|
|
6
5
|
from datetime import datetime
|
|
7
6
|
from enum import Enum
|
|
8
7
|
from typing import (
|
|
@@ -32,7 +31,12 @@ _T = TypeVar("_T")
|
|
|
32
31
|
class SerializeableContent:
|
|
33
32
|
_noSerialize: List[str] = []
|
|
34
33
|
_typeMapper: Optional[Dict[str, Any]] = None
|
|
35
|
-
|
|
34
|
+
_slack: Dict[str, Any] = {}
|
|
35
|
+
|
|
36
|
+
_planeClass: bool = False
|
|
37
|
+
_includeNone: bool = False
|
|
38
|
+
_debugPrintRef: bool = False
|
|
39
|
+
_includeSlack: bool = False
|
|
36
40
|
|
|
37
41
|
def __init__(self, ref=None):
|
|
38
42
|
if ref != None:
|
|
@@ -45,23 +49,25 @@ class SerializeableContent:
|
|
|
45
49
|
self,
|
|
46
50
|
ref,
|
|
47
51
|
selfClass,
|
|
48
|
-
fromInstance=None,
|
|
49
|
-
fromDict=None,
|
|
50
|
-
formatDict=None,
|
|
51
52
|
convertOtherType: Optional[Tuple[type, Callable[[Any], Any]]] = None,
|
|
52
53
|
):
|
|
53
|
-
|
|
54
|
+
if self._debugPrintRef:
|
|
55
|
+
print("FromRef", selfClass.__name__, "\n", self._dictToJson(ref))
|
|
54
56
|
|
|
55
|
-
# if not isinstance(ref, (selfClass, dict)) and convertOtherType:
|
|
56
|
-
# ref = convertOtherType(ref)
|
|
57
57
|
if convertOtherType and isinstance(ref, convertOtherType[0]):
|
|
58
58
|
ref = convertOtherType[1](ref)
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
serializableAncestors = tuple(
|
|
61
|
+
[
|
|
62
|
+
c
|
|
63
|
+
for c in inspect.getmro(selfClass)
|
|
64
|
+
if issubclass(c, SerializeableContent)
|
|
65
|
+
]
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
# if isinstance(ref, selfClass):
|
|
69
|
+
if isinstance(ref, serializableAncestors):
|
|
70
|
+
self.fromInstance(ref)
|
|
65
71
|
elif isinstance(ref, dict):
|
|
66
72
|
if hasattr(self, "_typeMapper") and self._typeMapper:
|
|
67
73
|
for k, t in self._typeMapper.items():
|
|
@@ -75,10 +81,7 @@ class SerializeableContent:
|
|
|
75
81
|
elements=ref, fieldName=k, fieldType=t, allowNone=True
|
|
76
82
|
)
|
|
77
83
|
|
|
78
|
-
|
|
79
|
-
fromDict(ref)
|
|
80
|
-
else:
|
|
81
|
-
self.fromDict(ref, formatDict=formatDict)
|
|
84
|
+
self.fromDict(ref)
|
|
82
85
|
else:
|
|
83
86
|
types: List[type] = [dict, type(self)]
|
|
84
87
|
if convertOtherType:
|
|
@@ -99,21 +102,73 @@ class SerializeableContent:
|
|
|
99
102
|
attrList = self._getAttrList()
|
|
100
103
|
for k in attrList:
|
|
101
104
|
if hasattr(ref, k):
|
|
102
|
-
|
|
105
|
+
try:
|
|
106
|
+
setattr(self, k, getattr(ref, k))
|
|
107
|
+
except AttributeError:
|
|
108
|
+
pass
|
|
103
109
|
|
|
104
|
-
def
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
def _getSlack(self, ignoreClasses: Optional[List[Type]] = None):
|
|
111
|
+
slack = {"class": type(self).__name__, "slack": {}}
|
|
112
|
+
if self._slack:
|
|
113
|
+
slack["slack"]["self"] = self._slack
|
|
114
|
+
attrList = self._getAttrList()
|
|
115
|
+
for k in attrList:
|
|
116
|
+
try:
|
|
117
|
+
if hasattr(self, k):
|
|
118
|
+
item = getattr(self, k)
|
|
119
|
+
if isinstance(item, list):
|
|
120
|
+
slacks = {}
|
|
121
|
+
for i, e in enumerate(item):
|
|
122
|
+
if ignoreClasses and any(
|
|
123
|
+
type(e) == c for c in ignoreClasses
|
|
124
|
+
):
|
|
125
|
+
continue
|
|
126
|
+
if isinstance(e, SerializeableContent):
|
|
127
|
+
s = e._getSlack(ignoreClasses=ignoreClasses)
|
|
128
|
+
if s["slack"]:
|
|
129
|
+
slacks[f"{k}[{i}]"] = s
|
|
130
|
+
if slacks:
|
|
131
|
+
slack["slack"].update(slacks)
|
|
132
|
+
|
|
133
|
+
if isinstance(item, SerializeableContent):
|
|
134
|
+
if ignoreClasses and any(
|
|
135
|
+
type(item) == c for c in ignoreClasses
|
|
136
|
+
):
|
|
137
|
+
continue
|
|
138
|
+
s = item._getSlack(ignoreClasses=ignoreClasses)
|
|
139
|
+
if s["slack"]:
|
|
140
|
+
slack["slack"][k] = s
|
|
141
|
+
except AttributeError:
|
|
142
|
+
pass
|
|
143
|
+
|
|
144
|
+
return slack
|
|
145
|
+
|
|
146
|
+
def _printSlackDict(self, slack: dict, prefix=""):
|
|
147
|
+
if not slack or "slack" not in slack or not slack["slack"]:
|
|
148
|
+
return
|
|
149
|
+
|
|
150
|
+
prefix += slack["class"] if prefix == "" else f"({slack['class']})"
|
|
151
|
+
if "self" in slack["slack"]:
|
|
152
|
+
print(f"{prefix}: '{slack['slack']['self']}'")
|
|
153
|
+
for k, v in slack["slack"].items():
|
|
154
|
+
if k == "self":
|
|
155
|
+
continue
|
|
156
|
+
self._printSlackDict(v, prefix + f".{k}")
|
|
110
157
|
|
|
111
|
-
|
|
112
|
-
|
|
158
|
+
def _printSlack(self, prefix="", ignoreClasses: Optional[List[Type]] = None):
|
|
159
|
+
self._printSlackDict(self._getSlack(ignoreClasses=ignoreClasses))
|
|
113
160
|
|
|
114
|
-
|
|
161
|
+
def fromDict(self, ref) -> None:
|
|
115
162
|
# print("ref", ref)
|
|
116
163
|
# print("ref", type(self).__name__)
|
|
164
|
+
if not hasattr(self, "_noSerialize"):
|
|
165
|
+
self._noSerialize = []
|
|
166
|
+
|
|
167
|
+
mappedKey = {
|
|
168
|
+
k: False
|
|
169
|
+
for k, v in ref.items()
|
|
170
|
+
if v is not None and k not in self._noSerialize
|
|
171
|
+
}
|
|
117
172
|
|
|
118
173
|
for k in dir(self):
|
|
119
174
|
# print(
|
|
@@ -123,19 +178,27 @@ class SerializeableContent:
|
|
|
123
178
|
# "->",
|
|
124
179
|
# ref[k] if k in ref else "NULL",
|
|
125
180
|
# )
|
|
126
|
-
|
|
181
|
+
|
|
182
|
+
try:
|
|
183
|
+
hasAttr = hasattr(self, k)
|
|
184
|
+
except (
|
|
185
|
+
EntityIncompleteException
|
|
186
|
+
): # while deserializing we want to ignore incomplete fields
|
|
187
|
+
hasAttr = False
|
|
188
|
+
|
|
189
|
+
if k in ref and hasAttr and not callable(getattr(self, k)):
|
|
127
190
|
try:
|
|
128
191
|
# print(" ", k, "->", ref[k])
|
|
129
192
|
setattr(self, k, ref[k])
|
|
193
|
+
mappedKey[k] = True
|
|
130
194
|
except AttributeError as e:
|
|
131
195
|
# print(f"[{type(self).__name__}] ERROR:", k, "->", ref[k], e)
|
|
132
196
|
pass
|
|
133
197
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
# if
|
|
137
|
-
# print(
|
|
138
|
-
# setattr(self, _k, ref[k])
|
|
198
|
+
self._slack = {k: ref[k] for k, v in mappedKey.items() if not v}
|
|
199
|
+
|
|
200
|
+
# if self._slack:
|
|
201
|
+
# print(type(self).__name__, "->", ", ".join(self._slack.keys()))
|
|
139
202
|
|
|
140
203
|
@classmethod
|
|
141
204
|
def toBaseclassString(cls, obj):
|
|
@@ -148,11 +211,13 @@ class SerializeableContent:
|
|
|
148
211
|
def toString(self):
|
|
149
212
|
return str(self)
|
|
150
213
|
|
|
151
|
-
|
|
152
|
-
def _serializeItem(cls, item):
|
|
214
|
+
def _serializeItem(self, item):
|
|
153
215
|
# print("serialize", item, hasattr(item, "__dict__"))
|
|
154
216
|
if hasattr(item, "toDict"):
|
|
155
|
-
|
|
217
|
+
if self._includeSlack and hasattr(item, "_toDictWithSlack"):
|
|
218
|
+
return item._toDictWithSlack()
|
|
219
|
+
else:
|
|
220
|
+
return item.toDict()
|
|
156
221
|
if isinstance(item, cast(Any, np.float32)):
|
|
157
222
|
return item.item()
|
|
158
223
|
elif hasattr(
|
|
@@ -199,6 +264,13 @@ class SerializeableContent:
|
|
|
199
264
|
|
|
200
265
|
return result
|
|
201
266
|
|
|
267
|
+
def _toDictWithSlack(self):
|
|
268
|
+
tmp = self._includeSlack
|
|
269
|
+
self._includeSlack = True
|
|
270
|
+
result = self.toDict()
|
|
271
|
+
self._includeSlack = tmp
|
|
272
|
+
return result
|
|
273
|
+
|
|
202
274
|
def toDict(self) -> Dict[str, Any]:
|
|
203
275
|
# print("toDict", type(self).__name__)
|
|
204
276
|
if not hasattr(self, "_noSerialize"):
|
|
@@ -233,9 +305,12 @@ class SerializeableContent:
|
|
|
233
305
|
# d[k] = "2021-12-01T00:00:00.000Z"
|
|
234
306
|
elif isinstance(a, Enum):
|
|
235
307
|
d[k] = a.value
|
|
236
|
-
elif a != None:
|
|
308
|
+
elif a != None or self._includeNone:
|
|
237
309
|
d[k] = self._serializeItem(a)
|
|
238
310
|
|
|
311
|
+
if self._includeSlack:
|
|
312
|
+
d.update({k: v for k, v in self._slack.items() if k not in d})
|
|
313
|
+
|
|
239
314
|
return d
|
|
240
315
|
|
|
241
316
|
@classmethod
|
|
@@ -274,12 +349,16 @@ class SerializeableContent:
|
|
|
274
349
|
self.toDict(), indent=indent, sort_keys=sort_keys, compact=compact
|
|
275
350
|
)
|
|
276
351
|
|
|
277
|
-
def printJson(self, validate=False):
|
|
278
|
-
print(
|
|
352
|
+
def printJson(self, indent=2, sort_keys=True, compact=False, validate=False):
|
|
353
|
+
print(
|
|
354
|
+
self.toJson(
|
|
355
|
+
validate=validate, indent=indent, sort_keys=sort_keys, compact=compact
|
|
356
|
+
)
|
|
357
|
+
)
|
|
279
358
|
|
|
280
359
|
@classmethod
|
|
281
360
|
def truncString(cls, text: str, length: int = 30) -> str:
|
|
282
|
-
return Tools.truncString(text=text, length=length)
|
|
361
|
+
return Tools.truncString(text=str(text), length=length)
|
|
283
362
|
|
|
284
363
|
@staticmethod
|
|
285
364
|
def delEntryFromDict(d: dict, entry: str):
|
|
@@ -515,11 +594,14 @@ class SerializeableContent:
|
|
|
515
594
|
excludeCharacters.append("line feed")
|
|
516
595
|
for k in text.keys():
|
|
517
596
|
if k not in excludeKeys:
|
|
518
|
-
text[k], messages =
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
597
|
+
text[k], messages = cast(
|
|
598
|
+
Any,
|
|
599
|
+
cls.replaceControlCharacters(
|
|
600
|
+
text[k],
|
|
601
|
+
excludeKeys=excludeKeys,
|
|
602
|
+
excludeCharacters=excludeCharacters,
|
|
603
|
+
mergeMessages=mergeMessages,
|
|
604
|
+
),
|
|
523
605
|
)
|
|
524
606
|
if messages:
|
|
525
607
|
for m in messages:
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import TYPE_CHECKING, List, Optional
|
|
3
|
+
|
|
4
|
+
from LOGS.Auxiliary import Tools
|
|
5
|
+
from LOGS.Entity.EntityMinimalWithIntId import EntityMinimalWithIntId
|
|
6
|
+
from LOGS.Interfaces.IEntityInterface import IEntityInterface
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class IHierarchyTypeRequest:
|
|
14
|
+
childrenOfParentIds: Optional[List[int]] = None
|
|
15
|
+
descendantsOfIds: Optional[List[int]] = None
|
|
16
|
+
isRoot: Optional[List[bool]] = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class IHierarchyType(IEntityInterface):
|
|
20
|
+
_inventoryName: Optional[str]
|
|
21
|
+
_isHierarchyRoot: Optional[bool]
|
|
22
|
+
_rootHierarchy: Optional[EntityMinimalWithIntId]
|
|
23
|
+
_parentTypes: Optional[List[EntityMinimalWithIntId]]
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def inventoryName(self) -> Optional[str]:
|
|
27
|
+
return self._inventoryName
|
|
28
|
+
|
|
29
|
+
@inventoryName.setter
|
|
30
|
+
def inventoryName(self, value):
|
|
31
|
+
self._inventoryName = Tools.checkAndConvert(
|
|
32
|
+
value, str, "inventoryName", allowNone=True
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def isHierarchyRoot(self) -> Optional[bool]:
|
|
37
|
+
return self._isHierarchyRoot
|
|
38
|
+
|
|
39
|
+
@isHierarchyRoot.setter
|
|
40
|
+
def isHierarchyRoot(self, value):
|
|
41
|
+
self._isHierarchyRoot = Tools.checkAndConvert(
|
|
42
|
+
value, bool, "isHierarchyRoot", allowNone=True
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def rootHierarchy(self) -> Optional[EntityMinimalWithIntId]:
|
|
47
|
+
return self._rootHierarchy
|
|
48
|
+
|
|
49
|
+
@rootHierarchy.setter
|
|
50
|
+
def rootHierarchy(self, value):
|
|
51
|
+
self._rootHierarchy = Tools.checkAndConvert(
|
|
52
|
+
value, EntityMinimalWithIntId, "rootHierarchy", allowNone=True
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def parentTypes(self) -> Optional[List[EntityMinimalWithIntId]]:
|
|
57
|
+
return self._parentTypes
|
|
58
|
+
|
|
59
|
+
@parentTypes.setter
|
|
60
|
+
def parentTypes(self, value):
|
|
61
|
+
self._parentTypes = Tools.checkListAndConvert(
|
|
62
|
+
value, EntityMinimalWithIntId, "parentTypes", allowNone=True
|
|
63
|
+
)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
|
-
from typing import TYPE_CHECKING, Optional
|
|
2
|
+
from typing import TYPE_CHECKING, Generic, Optional, Type, TypeVar, cast
|
|
3
3
|
|
|
4
4
|
from LOGS.Auxiliary import Tools
|
|
5
|
+
from LOGS.Entity.SerializeableContent import SerializeableClass
|
|
5
6
|
from LOGS.Interfaces.IEntityInterface import IEntityInterface
|
|
6
7
|
|
|
7
8
|
if TYPE_CHECKING:
|
|
@@ -13,15 +14,38 @@ class IPermissionedEntityRequest:
|
|
|
13
14
|
includePermissions: Optional[bool] = None
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
class
|
|
17
|
-
|
|
17
|
+
class IPermissionModel:
|
|
18
|
+
edit: Optional[bool] = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class GenericPermission(IPermissionModel, SerializeableClass):
|
|
22
|
+
edit: Optional[bool] = False
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
_PERMISSION = TypeVar("_PERMISSION", bound=IPermissionModel)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class IPermissionedEntity(Generic[_PERMISSION], IEntityInterface):
|
|
29
|
+
_permissionType: Optional[Type[_PERMISSION]] = None
|
|
30
|
+
|
|
31
|
+
_permissions: Optional[_PERMISSION] = None
|
|
18
32
|
|
|
19
33
|
@property
|
|
20
|
-
def permissions(self) -> Optional[
|
|
34
|
+
def permissions(self) -> Optional[_PERMISSION]:
|
|
21
35
|
return self._permissions
|
|
22
36
|
|
|
23
37
|
@permissions.setter
|
|
24
38
|
def permissions(self, value):
|
|
39
|
+
if not self._permissionType:
|
|
40
|
+
raise NotImplementedError("Permission type must be set")
|
|
41
|
+
|
|
25
42
|
self._permissions = Tools.checkAndConvert(
|
|
26
|
-
value,
|
|
43
|
+
value,
|
|
44
|
+
cast(Type[_PERMISSION], self._permissionType),
|
|
45
|
+
"permissions",
|
|
46
|
+
allowNone=True,
|
|
27
47
|
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class GenericPermissionEntity(IPermissionedEntity[GenericPermission]):
|
|
51
|
+
_permissionType: Type[GenericPermission] = GenericPermission
|