logs-py 2.9.6__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.

Files changed (146) hide show
  1. LOGS/Auxiliary/DateTimeConverter.py +11 -1
  2. LOGS/Auxiliary/Exceptions.py +40 -4
  3. LOGS/Auxiliary/LOGSErrorResponse.py +4 -1
  4. LOGS/Auxiliary/MinimalModelGenerator.py +88 -28
  5. LOGS/Auxiliary/Tools.py +11 -0
  6. LOGS/Converter/Conversion.py +248 -0
  7. LOGS/Converter/Converter.py +96 -0
  8. LOGS/Converter/ConverterParameter.py +88 -0
  9. LOGS/Converter/ExportParamters.py +89 -0
  10. LOGS/Converter/__init__.py +13 -0
  11. LOGS/Entities/Bridge.py +6 -3
  12. LOGS/Entities/CustomField.py +96 -91
  13. LOGS/Entities/CustomFieldModels.py +57 -0
  14. LOGS/Entities/CustomFieldRelations.py +10 -0
  15. LOGS/Entities/CustomFieldRequestParameter.py +43 -15
  16. LOGS/Entities/CustomFieldValue.py +88 -0
  17. LOGS/Entities/CustomFieldValueConverter.py +66 -0
  18. LOGS/Entities/CustomType.py +187 -0
  19. LOGS/Entities/CustomTypeEntityType.py +11 -0
  20. LOGS/Entities/CustomTypeMinimal.py +8 -0
  21. LOGS/Entities/CustomTypeRelations.py +59 -0
  22. LOGS/Entities/CustomTypeRequestParameter.py +61 -0
  23. LOGS/Entities/CustomTypeSection.py +39 -0
  24. LOGS/Entities/CustomTypes.py +12 -0
  25. LOGS/Entities/DataSource.py +28 -14
  26. LOGS/Entities/Dataset.py +274 -136
  27. LOGS/Entities/DatasetCreator.py +23 -72
  28. LOGS/Entities/DatasetInfo.py +23 -2
  29. LOGS/Entities/DatasetModels.py +31 -0
  30. LOGS/Entities/DatasetRequestParameter.py +45 -32
  31. LOGS/Entities/Datatrack.py +74 -30
  32. LOGS/Entities/DatatrackFormattedTable.py +25 -0
  33. LOGS/Entities/DatatrackGeneric.py +34 -0
  34. LOGS/Entities/DatatrackImage.py +25 -0
  35. LOGS/Entities/DatatrackNumericArray.py +9 -39
  36. LOGS/Entities/DatatrackNumericMatrix.py +86 -0
  37. LOGS/Entities/DocumentRequestParameter.py +2 -2
  38. LOGS/Entities/EntitiesRequestParameter.py +2 -2
  39. LOGS/Entities/Experiment.py +3 -3
  40. LOGS/Entities/FileExcludePattern.py +8 -0
  41. LOGS/Entities/FormatFormat.py +22 -1
  42. LOGS/Entities/FormatFormatRequestParameter.py +2 -1
  43. LOGS/Entities/FormatFormats.py +1 -1
  44. LOGS/Entities/FormattedTable/DatatypeFormattedTable.py +135 -0
  45. LOGS/Entities/FormattedTable/DatatypeFormattedTableCell.py +108 -0
  46. LOGS/Entities/FormattedTable/DatatypeFormattedTableSettings.py +11 -0
  47. LOGS/Entities/FormattedTable/__init__.py +9 -0
  48. LOGS/Entities/ILiterarTypedEntity.py +19 -0
  49. LOGS/Entities/Instrument.py +3 -3
  50. LOGS/Entities/Inventories.py +12 -0
  51. LOGS/Entities/Inventory.py +95 -0
  52. LOGS/Entities/InventoryMinimal.py +20 -0
  53. LOGS/Entities/InventoryRelations.py +23 -0
  54. LOGS/Entities/InventoryRequestParameter.py +53 -0
  55. LOGS/Entities/LabNotebook.py +37 -0
  56. LOGS/Entities/LabNotebookEntry.py +47 -24
  57. LOGS/Entities/LabNotebookEntryContent/BasicAttribute.py +15 -0
  58. LOGS/Entities/LabNotebookEntryContent/EntityAttribute.py +85 -0
  59. LOGS/Entities/LabNotebookEntryContent/EntryContentBlockquote.py +13 -0
  60. LOGS/Entities/LabNotebookEntryContent/EntryContentBulletList.py +17 -0
  61. LOGS/Entities/LabNotebookEntryContent/EntryContentCallout.py +40 -0
  62. LOGS/Entities/LabNotebookEntryContent/EntryContentContentPlaceholderNode.py +31 -0
  63. LOGS/Entities/LabNotebookEntryContent/EntryContentConverter.py +207 -0
  64. LOGS/Entities/LabNotebookEntryContent/EntryContentDocument.py +8 -0
  65. LOGS/Entities/LabNotebookEntryContent/EntryContentEntity.py +13 -0
  66. LOGS/Entities/LabNotebookEntryContent/EntryContentEntityMention.py +31 -0
  67. LOGS/Entities/LabNotebookEntryContent/EntryContentHeading.py +33 -0
  68. LOGS/Entities/LabNotebookEntryContent/EntryContentHorizontalRule.py +12 -0
  69. LOGS/Entities/LabNotebookEntryContent/EntryContentItem.py +37 -0
  70. LOGS/Entities/LabNotebookEntryContent/EntryContentListItem.py +49 -0
  71. LOGS/Entities/LabNotebookEntryContent/EntryContentOrderedList.py +31 -0
  72. LOGS/Entities/LabNotebookEntryContent/EntryContentParagraph.py +13 -0
  73. LOGS/Entities/LabNotebookEntryContent/EntryContentTable.py +17 -0
  74. LOGS/Entities/LabNotebookEntryContent/EntryContentTableCell.py +40 -0
  75. LOGS/Entities/LabNotebookEntryContent/EntryContentTableRow.py +8 -0
  76. LOGS/Entities/LabNotebookEntryContent/EntryContentTaskList.py +17 -0
  77. LOGS/Entities/LabNotebookEntryContent/EntryContentTaskListItem.py +31 -0
  78. LOGS/Entities/LabNotebookEntryContent/EntryContentText.py +33 -0
  79. LOGS/Entities/LabNotebookEntryContent/IEntryContentWithAttribute.py +23 -0
  80. LOGS/Entities/LabNotebookEntryContent/IEntryContentWithContent.py +38 -0
  81. LOGS/Entities/LabNotebookEntryContent/IEntryContentWithTextAttribute.py +16 -0
  82. LOGS/Entities/LabNotebookEntryContent/TextAttribute.py +46 -0
  83. LOGS/Entities/LabNotebookEntryContent/TextMarkAtributes.py +64 -0
  84. LOGS/Entities/LabNotebookEntryContent/TextMarkConverter.py +45 -0
  85. LOGS/Entities/LabNotebookEntryContent/TextMarks.py +71 -0
  86. LOGS/Entities/LabNotebookEntryContent/__init__.py +34 -0
  87. LOGS/Entities/LabNotebookEntryRequestParameter.py +2 -0
  88. LOGS/Entities/LabNotebookExperiment.py +52 -0
  89. LOGS/Entities/LabNotebookExperimentMinimal.py +8 -0
  90. LOGS/Entities/LabNotebookExperimentRequestParameter.py +49 -0
  91. LOGS/Entities/LabNotebookExperiments.py +16 -0
  92. LOGS/Entities/LabNotebookMinimal.py +19 -0
  93. LOGS/Entities/LabNotebookModels.py +14 -0
  94. LOGS/Entities/LabNotebookRequestParameter.py +43 -0
  95. LOGS/Entities/LabNotebooks.py +12 -0
  96. LOGS/Entities/Method.py +3 -3
  97. LOGS/Entities/ParserLog.py +4 -0
  98. LOGS/Entities/Person.py +2 -2
  99. LOGS/Entities/Project.py +7 -7
  100. LOGS/Entities/{ProjectUserPermission.py → ProjectPersonPermission.py} +14 -4
  101. LOGS/Entities/Role.py +3 -3
  102. LOGS/Entities/RunState.py +1 -0
  103. LOGS/Entities/Sample.py +36 -57
  104. LOGS/Entities/SampleRequestParameter.py +30 -15
  105. LOGS/Entities/Track.py +8 -4
  106. LOGS/Entities/TrackData.py +11 -0
  107. LOGS/Entities/TrackImage.py +21 -0
  108. LOGS/Entities/TrackImageData.py +20 -0
  109. LOGS/Entities/TrackMatrix.py +28 -0
  110. LOGS/Entities/TrackMatrixData.py +22 -0
  111. LOGS/Entities/TrackTable.py +21 -0
  112. LOGS/Entities/TrackTableData.py +22 -0
  113. LOGS/Entities/TrackXY.py +5 -1
  114. LOGS/Entities/TrackXYComplex.py +1 -1
  115. LOGS/Entities/__init__.py +26 -7
  116. LOGS/Entity/ConnectedEntity.py +39 -1
  117. LOGS/Entity/Entity.py +9 -14
  118. LOGS/Entity/SerializeableContent.py +62 -5
  119. LOGS/Interfaces/IHierarchyType.py +63 -0
  120. LOGS/Interfaces/IPermissionedEntity.py +29 -5
  121. LOGS/Interfaces/IProjectBased.py +1 -1
  122. LOGS/Interfaces/ITypedEntity.py +69 -12
  123. LOGS/Interfaces/IVersionedEntity.py +39 -0
  124. LOGS/LOGS.py +137 -46
  125. LOGS/LOGSConnection.py +52 -24
  126. LOGS/LOGSOptions.py +8 -0
  127. LOGS/Parameters/Color.py +92 -0
  128. LOGS/Parameters/ParameterBase.py +55 -0
  129. LOGS/Parameters/ParameterConverter.py +24 -0
  130. LOGS/Parameters/ParameterElement.py +99 -0
  131. LOGS/Parameters/ParameterList.py +52 -0
  132. LOGS/Parameters/ParameterTable.py +64 -0
  133. LOGS/Parameters/__init__.py +13 -0
  134. LOGS/__init__.py +1 -0
  135. {logs_py-2.9.6.dist-info → logs_py-3.0.0.dist-info}/METADATA +2 -1
  136. logs_py-3.0.0.dist-info/RECORD +263 -0
  137. LOGS/Entities/CustomFieldEnums.py +0 -25
  138. LOGS/Entities/DatasetType.py +0 -7
  139. LOGS/Entities/DatasetTypeMinimal.py +0 -8
  140. LOGS/Entities/SampleType.py +0 -34
  141. LOGS/Entities/SampleTypeMinimal.py +0 -8
  142. LOGS/Entities/SampleTypeRequestParameter.py +0 -8
  143. LOGS/Entities/SampleTypes.py +0 -12
  144. logs_py-2.9.6.dist-info/RECORD +0 -183
  145. {logs_py-2.9.6.dist-info → logs_py-3.0.0.dist-info}/WHEEL +0 -0
  146. {logs_py-2.9.6.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(value, TrackXYData, "data")
38
+ self._datatracks = self.checkAndConvertNullable(
39
+ value, TrackXYData, "datatracks"
40
+ )
@@ -47,5 +47,5 @@ class TrackXYComplex(Track):
47
47
  @datatracks.setter
48
48
  def datatracks(self, value):
49
49
  self._datatracks = self.checkAndConvertNullable(
50
- value, TrackXYComplexData, "data"
50
+ value, TrackXYComplexData, "datatracks"
51
51
  )
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 .CustomFieldEnums import *
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 .LabNotebookEntry import *
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 *
@@ -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
- if not self._endpoint:
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 self._getConnection(), self._endpoint, self.id
40
+ return connection, endpoint, self.id
49
41
 
50
42
  def __str__(self):
51
- s = (" name:'%s'" % getattr(self, "name")) if hasattr(self, "name") else ""
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 = f"'{getattr(self, 'name')}'" if hasattr(self, "name") else None
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),
@@ -53,14 +53,20 @@ class SerializeableContent:
53
53
  ):
54
54
  if self._debugPrintRef:
55
55
  print("FromRef", selfClass.__name__, "\n", self._dictToJson(ref))
56
- # print("FromRef", selfClass.__name__, self._json_schema)
57
56
 
58
- # if not isinstance(ref, (selfClass, dict)) and convertOtherType:
59
- # ref = convertOtherType(ref)
60
57
  if convertOtherType and isinstance(ref, convertOtherType[0]):
61
58
  ref = convertOtherType[1](ref)
62
59
 
63
- if isinstance(ref, selfClass):
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):
64
70
  self.fromInstance(ref)
65
71
  elif isinstance(ref, dict):
66
72
  if hasattr(self, "_typeMapper") and self._typeMapper:
@@ -101,6 +107,57 @@ class SerializeableContent:
101
107
  except AttributeError:
102
108
  pass
103
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}")
157
+
158
+ def _printSlack(self, prefix="", ignoreClasses: Optional[List[Type]] = None):
159
+ self._printSlackDict(self._getSlack(ignoreClasses=ignoreClasses))
160
+
104
161
  def fromDict(self, ref) -> None:
105
162
  # print("ref", ref)
106
163
  # print("ref", type(self).__name__)
@@ -301,7 +358,7 @@ class SerializeableContent:
301
358
 
302
359
  @classmethod
303
360
  def truncString(cls, text: str, length: int = 30) -> str:
304
- return Tools.truncString(text=text, length=length)
361
+ return Tools.truncString(text=str(text), length=length)
305
362
 
306
363
  @staticmethod
307
364
  def delEntryFromDict(d: dict, entry: str):
@@ -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, Dict, 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 IPermissionedEntity(IEntityInterface):
17
- _permissions: Optional[Dict[str, bool]] = None
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[Dict[str, bool]]:
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, dict, "permissions", allowNone=True
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
@@ -10,7 +10,7 @@ if TYPE_CHECKING:
10
10
 
11
11
  @dataclass
12
12
  class IProjectBasedRequest:
13
- projects: Optional[List[str]] = None
13
+ projectIds: Optional[List[int]] = None
14
14
 
15
15
 
16
16
  class IProjectBased(IEntityInterface):
@@ -1,28 +1,85 @@
1
1
  from dataclasses import dataclass
2
- from typing import TYPE_CHECKING, Any, Dict, Optional
2
+ from typing import TYPE_CHECKING, List, Optional, Sequence, Union
3
3
 
4
4
  from LOGS.Auxiliary import Tools
5
+ from LOGS.Auxiliary.MinimalModelGenerator import MinimalFromSingle
6
+ from LOGS.Entities.CustomFieldValue import (
7
+ CustomFieldValue,
8
+ CustomSectionValue,
9
+ ICustomValue,
10
+ )
11
+ from LOGS.Entities.CustomFieldValueConverter import CustomFieldValueConverter
5
12
  from LOGS.Interfaces.IEntityInterface import IEntityInterface
6
13
 
7
14
  if TYPE_CHECKING:
8
- pass
15
+ from LOGS.Entities.CustomTypeMinimal import CustomTypeMinimal
9
16
 
10
17
 
11
18
  @dataclass
12
19
  class ITypedEntityRequest:
13
- includeCustomFields: Optional[bool] = None
14
- customFields: Optional[Dict[str, Any]] = None
20
+ includeCustomFields: Optional[List[bool]] = None
15
21
 
16
22
 
17
23
  class ITypedEntity(IEntityInterface):
18
- _customFields: Optional[Dict[str, Any]] = None
24
+ _customType: Optional["CustomTypeMinimal"] = None
25
+ _customValues: Optional[
26
+ Sequence[Union["CustomFieldValue", "CustomSectionValue"]]
27
+ ] = None
28
+
29
+ def _customValueConverter(self, value):
30
+ return Tools.checkListAndConvert(
31
+ value, ICustomValue, "customValues", allowNone=True
32
+ )
19
33
 
20
34
  @property
21
- def customFields(self) -> Optional[Dict[str, Any]]:
22
- return self._customFields
35
+ def customType(self) -> Optional["CustomTypeMinimal"]:
36
+ return self._customType
23
37
 
24
- @customFields.setter
25
- def customFields(self, value):
26
- self._customFields = Tools.checkAndConvert(
27
- value, dict, "customFields", allowNone=True
28
- )
38
+ @customType.setter
39
+ def customType(self, value):
40
+ self._customType = MinimalFromSingle(value, "CustomTypeMinimal", "customType")
41
+
42
+ @property
43
+ def customValues(
44
+ self,
45
+ ) -> Optional[
46
+ Union[
47
+ Sequence[Union["CustomFieldValue", "CustomSectionValue"]],
48
+ Union["CustomFieldValue", "CustomSectionValue"],
49
+ ]
50
+ ]:
51
+ return self._customValues
52
+
53
+ @customValues.setter
54
+ def customValues(self, value):
55
+ self._customValues = CustomFieldValueConverter.convert(value, "customValues")
56
+
57
+ def _extractCustomFieldValue(
58
+ self,
59
+ value: Union[
60
+ CustomFieldValue,
61
+ CustomSectionValue,
62
+ Sequence[Union[CustomFieldValue, CustomSectionValue]],
63
+ ],
64
+ ) -> List[CustomFieldValue]:
65
+ if isinstance(value, list):
66
+ result: List[CustomFieldValue] = []
67
+ for v in value:
68
+ result += self._extractCustomFieldValue(v)
69
+ return result
70
+ if isinstance(value, CustomFieldValue):
71
+ return [value]
72
+ if isinstance(value, CustomSectionValue):
73
+ if value.content:
74
+ return self._extractCustomFieldValue(value.content)
75
+
76
+ return []
77
+
78
+ @property
79
+ def customFieldValues(
80
+ self,
81
+ ) -> Optional[List["CustomFieldValue"]]:
82
+ if self.customValues == None:
83
+ return None
84
+
85
+ return self._extractCustomFieldValue(self.customValues)
@@ -0,0 +1,39 @@
1
+ from dataclasses import dataclass
2
+ from typing import TYPE_CHECKING, Generic, List, Optional, TypeVar, Union
3
+
4
+ from LOGS.Auxiliary import Tools
5
+ from LOGS.Interfaces.ICreationRecord import ICreationRecord, ICreationRecordRequest
6
+ from LOGS.Interfaces.IModificationRecord import (
7
+ IModificationRecord,
8
+ IModificationRecordRequest,
9
+ )
10
+ from LOGS.Interfaces.ISoftDeletable import ISoftDeletable, ISoftDeletableRequest
11
+
12
+ if TYPE_CHECKING:
13
+ pass
14
+
15
+ _idType = TypeVar("_idType", bound=Union[int, str])
16
+
17
+
18
+ @dataclass
19
+ class IVersionedEntityRequest(
20
+ Generic[_idType],
21
+ ICreationRecordRequest,
22
+ IModificationRecordRequest,
23
+ ISoftDeletableRequest,
24
+ ):
25
+ originalIds: Optional[List[_idType]] = None
26
+ versionIds: Optional[List[int]] = None
27
+ versions: Optional[List[int]] = None
28
+
29
+
30
+ class IVersionedEntity(ICreationRecord, IModificationRecord, ISoftDeletable):
31
+ _version: Optional[int] = None
32
+
33
+ @property
34
+ def version(self) -> Optional[int]:
35
+ return self._version
36
+
37
+ @version.setter
38
+ def version(self, value):
39
+ self._version = Tools.checkAndConvert(value, int, "version", allowNone=True)