logs-py 4.0.7__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.
Files changed (251) hide show
  1. LOGS/Auxiliary/CheckClassName.py +1075 -0
  2. LOGS/Auxiliary/Constants.py +99 -0
  3. LOGS/Auxiliary/CustomEntityClassGenerator.py +254 -0
  4. LOGS/Auxiliary/CustomFieldClassGenerator.py +115 -0
  5. LOGS/Auxiliary/CustomFieldValueTypeChecker.py +168 -0
  6. LOGS/Auxiliary/CustomSectionClassGenerator.py +113 -0
  7. LOGS/Auxiliary/CustomTypeClassGenerator.py +147 -0
  8. LOGS/Auxiliary/DateTimeConverter.py +66 -0
  9. LOGS/Auxiliary/Decorators.py +109 -0
  10. LOGS/Auxiliary/Exceptions.py +341 -0
  11. LOGS/Auxiliary/LOGSErrorResponse.py +89 -0
  12. LOGS/Auxiliary/MinimalModelGenerator.py +236 -0
  13. LOGS/Auxiliary/ParameterHelper.py +56 -0
  14. LOGS/Auxiliary/ReplaceMessage.py +13 -0
  15. LOGS/Auxiliary/Tools.py +432 -0
  16. LOGS/Auxiliary/__init__.py +15 -0
  17. LOGS/Converter/Conversion.py +248 -0
  18. LOGS/Converter/Converter.py +96 -0
  19. LOGS/Converter/ConverterParameter.py +88 -0
  20. LOGS/Converter/DateTimeRange.py +58 -0
  21. LOGS/Converter/ExportParameters.py +89 -0
  22. LOGS/Converter/__init__.py +13 -0
  23. LOGS/Entities/Attachment.py +84 -0
  24. LOGS/Entities/AttachmentMinimal.py +8 -0
  25. LOGS/Entities/AttachmentRequestParameter.py +42 -0
  26. LOGS/Entities/Attachments.py +53 -0
  27. LOGS/Entities/AutoloadFileInfo.py +12 -0
  28. LOGS/Entities/AutoloadStatusError.py +7 -0
  29. LOGS/Entities/AxisNaming.py +33 -0
  30. LOGS/Entities/AxisZoom.py +33 -0
  31. LOGS/Entities/Bridge.py +165 -0
  32. LOGS/Entities/BridgeClientInfo.py +93 -0
  33. LOGS/Entities/BridgeMinimal.py +8 -0
  34. LOGS/Entities/BridgeRequestParameter.py +49 -0
  35. LOGS/Entities/BridgeType.py +7 -0
  36. LOGS/Entities/Bridges.py +12 -0
  37. LOGS/Entities/CustomField.py +243 -0
  38. LOGS/Entities/CustomFieldMinimal.py +8 -0
  39. LOGS/Entities/CustomFieldModels.py +111 -0
  40. LOGS/Entities/CustomFieldRequestParameter.py +69 -0
  41. LOGS/Entities/CustomFieldSearchQuery.py +40 -0
  42. LOGS/Entities/CustomFields.py +12 -0
  43. LOGS/Entities/CustomType.py +212 -0
  44. LOGS/Entities/CustomTypeMinimal.py +8 -0
  45. LOGS/Entities/CustomTypeRequestParameter.py +60 -0
  46. LOGS/Entities/CustomTypeSection.py +63 -0
  47. LOGS/Entities/CustomTypes.py +12 -0
  48. LOGS/Entities/DataFormat.py +97 -0
  49. LOGS/Entities/DataFormatInstrument.py +18 -0
  50. LOGS/Entities/DataFormatInstrumentMinimal.py +8 -0
  51. LOGS/Entities/DataFormatInstrumentRequestParameter.py +17 -0
  52. LOGS/Entities/DataFormatInstruments.py +16 -0
  53. LOGS/Entities/DataFormatMinimal.py +18 -0
  54. LOGS/Entities/DataFormatRequestParameter.py +21 -0
  55. LOGS/Entities/DataFormats.py +12 -0
  56. LOGS/Entities/DataSource.py +218 -0
  57. LOGS/Entities/DataSourceConnectionStatus.py +12 -0
  58. LOGS/Entities/DataSourceMinimal.py +8 -0
  59. LOGS/Entities/DataSourceRequestParameter.py +57 -0
  60. LOGS/Entities/DataSourceStatus.py +108 -0
  61. LOGS/Entities/DataSourceStatusIterator.py +16 -0
  62. LOGS/Entities/DataSourceStatusRequestParameter.py +31 -0
  63. LOGS/Entities/DataSources.py +12 -0
  64. LOGS/Entities/Dataset.py +439 -0
  65. LOGS/Entities/DatasetBase.py +196 -0
  66. LOGS/Entities/DatasetCreator.py +148 -0
  67. LOGS/Entities/DatasetInfo.py +147 -0
  68. LOGS/Entities/DatasetMatchTypes.py +157 -0
  69. LOGS/Entities/DatasetMatching.py +196 -0
  70. LOGS/Entities/DatasetMinimal.py +8 -0
  71. LOGS/Entities/DatasetModels.py +33 -0
  72. LOGS/Entities/DatasetRequestParameter.py +92 -0
  73. LOGS/Entities/DatasetTemplate.py +23 -0
  74. LOGS/Entities/DatasetUploadParameter.py +14 -0
  75. LOGS/Entities/Datasets.py +142 -0
  76. LOGS/Entities/Datatrack.py +179 -0
  77. LOGS/Entities/DatatrackFormattedTable.py +25 -0
  78. LOGS/Entities/DatatrackGeneric.py +34 -0
  79. LOGS/Entities/DatatrackImage.py +25 -0
  80. LOGS/Entities/DatatrackNumericArray.py +30 -0
  81. LOGS/Entities/DatatrackNumericMatrix.py +98 -0
  82. LOGS/Entities/Entities.py +71 -0
  83. LOGS/Entities/EntitiesRequestParameter.py +18 -0
  84. LOGS/Entities/EntityOriginWriteModelWithId.py +15 -0
  85. LOGS/Entities/FileEntry.py +138 -0
  86. LOGS/Entities/FileExcludePattern.py +8 -0
  87. LOGS/Entities/FormatMetaData.py +56 -0
  88. LOGS/Entities/FormattedTable/DatatypeFormattedTable.py +135 -0
  89. LOGS/Entities/FormattedTable/DatatypeFormattedTableCell.py +108 -0
  90. LOGS/Entities/FormattedTable/DatatypeFormattedTableSettings.py +11 -0
  91. LOGS/Entities/FormattedTable/__init__.py +9 -0
  92. LOGS/Entities/HierarchyLeaf.py +15 -0
  93. LOGS/Entities/HierarchyNode.py +40 -0
  94. LOGS/Entities/ILiteraryTypedEntity.py +19 -0
  95. LOGS/Entities/InventoryItem.py +102 -0
  96. LOGS/Entities/InventoryItemMinimal.py +25 -0
  97. LOGS/Entities/InventoryItemRequestParameter.py +58 -0
  98. LOGS/Entities/InventoryItems.py +12 -0
  99. LOGS/Entities/LabNotebook.py +33 -0
  100. LOGS/Entities/LabNotebookEntries.py +16 -0
  101. LOGS/Entities/LabNotebookEntry.py +106 -0
  102. LOGS/Entities/LabNotebookEntryContent/BasicAttribute.py +15 -0
  103. LOGS/Entities/LabNotebookEntryContent/EntityAttribute.py +85 -0
  104. LOGS/Entities/LabNotebookEntryContent/EntryContentBlockquote.py +13 -0
  105. LOGS/Entities/LabNotebookEntryContent/EntryContentBulletList.py +17 -0
  106. LOGS/Entities/LabNotebookEntryContent/EntryContentCallout.py +40 -0
  107. LOGS/Entities/LabNotebookEntryContent/EntryContentContentPlaceholderNode.py +31 -0
  108. LOGS/Entities/LabNotebookEntryContent/EntryContentConverter.py +207 -0
  109. LOGS/Entities/LabNotebookEntryContent/EntryContentDocument.py +8 -0
  110. LOGS/Entities/LabNotebookEntryContent/EntryContentEntity.py +13 -0
  111. LOGS/Entities/LabNotebookEntryContent/EntryContentEntityMention.py +31 -0
  112. LOGS/Entities/LabNotebookEntryContent/EntryContentHeading.py +33 -0
  113. LOGS/Entities/LabNotebookEntryContent/EntryContentHorizontalRule.py +12 -0
  114. LOGS/Entities/LabNotebookEntryContent/EntryContentItem.py +37 -0
  115. LOGS/Entities/LabNotebookEntryContent/EntryContentListItem.py +49 -0
  116. LOGS/Entities/LabNotebookEntryContent/EntryContentOrderedList.py +31 -0
  117. LOGS/Entities/LabNotebookEntryContent/EntryContentParagraph.py +13 -0
  118. LOGS/Entities/LabNotebookEntryContent/EntryContentTable.py +17 -0
  119. LOGS/Entities/LabNotebookEntryContent/EntryContentTableCell.py +40 -0
  120. LOGS/Entities/LabNotebookEntryContent/EntryContentTableRow.py +8 -0
  121. LOGS/Entities/LabNotebookEntryContent/EntryContentTaskList.py +17 -0
  122. LOGS/Entities/LabNotebookEntryContent/EntryContentTaskListItem.py +31 -0
  123. LOGS/Entities/LabNotebookEntryContent/EntryContentText.py +33 -0
  124. LOGS/Entities/LabNotebookEntryContent/IEntryContentWithAttribute.py +23 -0
  125. LOGS/Entities/LabNotebookEntryContent/IEntryContentWithContent.py +38 -0
  126. LOGS/Entities/LabNotebookEntryContent/IEntryContentWithTextAttribute.py +16 -0
  127. LOGS/Entities/LabNotebookEntryContent/TextAttribute.py +46 -0
  128. LOGS/Entities/LabNotebookEntryContent/TextMarkAtributes.py +64 -0
  129. LOGS/Entities/LabNotebookEntryContent/TextMarkConverter.py +45 -0
  130. LOGS/Entities/LabNotebookEntryContent/TextMarks.py +71 -0
  131. LOGS/Entities/LabNotebookEntryContent/__init__.py +34 -0
  132. LOGS/Entities/LabNotebookEntryMinimal.py +8 -0
  133. LOGS/Entities/LabNotebookEntryRequestParameter.py +59 -0
  134. LOGS/Entities/LabNotebookExperiment.py +58 -0
  135. LOGS/Entities/LabNotebookExperimentMinimal.py +8 -0
  136. LOGS/Entities/LabNotebookExperimentRequestParameter.py +52 -0
  137. LOGS/Entities/LabNotebookExperiments.py +16 -0
  138. LOGS/Entities/LabNotebookMinimal.py +8 -0
  139. LOGS/Entities/LabNotebookModels.py +14 -0
  140. LOGS/Entities/LabNotebookRequestParameter.py +42 -0
  141. LOGS/Entities/LabNotebookTemplate.py +42 -0
  142. LOGS/Entities/LabNotebookTemplateMinimal.py +8 -0
  143. LOGS/Entities/LabNotebookTemplateRequestParameter.py +38 -0
  144. LOGS/Entities/LabNotebookTemplates.py +16 -0
  145. LOGS/Entities/LabNotebooks.py +12 -0
  146. LOGS/Entities/Method.py +66 -0
  147. LOGS/Entities/MethodMinimal.py +8 -0
  148. LOGS/Entities/MethodRequestParameter.py +16 -0
  149. LOGS/Entities/Methods.py +12 -0
  150. LOGS/Entities/Origin.py +53 -0
  151. LOGS/Entities/OriginMinimal.py +8 -0
  152. LOGS/Entities/OriginRequestParameter.py +28 -0
  153. LOGS/Entities/Origins.py +12 -0
  154. LOGS/Entities/ParserLog.py +49 -0
  155. LOGS/Entities/Permission.py +9 -0
  156. LOGS/Entities/Person.py +145 -0
  157. LOGS/Entities/PersonCategory.py +12 -0
  158. LOGS/Entities/PersonMinimal.py +8 -0
  159. LOGS/Entities/PersonRequestParameter.py +58 -0
  160. LOGS/Entities/Persons.py +12 -0
  161. LOGS/Entities/Project.py +52 -0
  162. LOGS/Entities/ProjectMinimal.py +8 -0
  163. LOGS/Entities/ProjectPersonPermission.py +102 -0
  164. LOGS/Entities/ProjectRequestParameter.py +58 -0
  165. LOGS/Entities/Projects.py +12 -0
  166. LOGS/Entities/Role.py +94 -0
  167. LOGS/Entities/RoleMinimal.py +8 -0
  168. LOGS/Entities/RoleRequestParameter.py +40 -0
  169. LOGS/Entities/Roles.py +12 -0
  170. LOGS/Entities/RunState.py +9 -0
  171. LOGS/Entities/Sample.py +53 -0
  172. LOGS/Entities/SampleMinimal.py +8 -0
  173. LOGS/Entities/SampleRequestParameter.py +54 -0
  174. LOGS/Entities/Samples.py +12 -0
  175. LOGS/Entities/SharedContent.py +87 -0
  176. LOGS/Entities/SharedContentMinimal.py +8 -0
  177. LOGS/Entities/SharedContentRequestParameter.py +38 -0
  178. LOGS/Entities/SharedContents.py +12 -0
  179. LOGS/Entities/Signature.py +60 -0
  180. LOGS/Entities/Track.py +93 -0
  181. LOGS/Entities/TrackData.py +20 -0
  182. LOGS/Entities/TrackImage.py +21 -0
  183. LOGS/Entities/TrackImageData.py +20 -0
  184. LOGS/Entities/TrackMatrix.py +28 -0
  185. LOGS/Entities/TrackMatrixData.py +22 -0
  186. LOGS/Entities/TrackSettings.py +55 -0
  187. LOGS/Entities/TrackTable.py +21 -0
  188. LOGS/Entities/TrackTableData.py +22 -0
  189. LOGS/Entities/TrackXY.py +40 -0
  190. LOGS/Entities/TrackXYComplex.py +51 -0
  191. LOGS/Entities/TrackXYComplexData.py +50 -0
  192. LOGS/Entities/TrackXYData.py +31 -0
  193. LOGS/Entities/Vendor.py +40 -0
  194. LOGS/Entities/VendorMinimal.py +8 -0
  195. LOGS/Entities/VendorRequestParameter.py +17 -0
  196. LOGS/Entities/Vendors.py +12 -0
  197. LOGS/Entities/__init__.py +118 -0
  198. LOGS/Entity/ConnectedEntity.py +170 -0
  199. LOGS/Entity/Entity.py +203 -0
  200. LOGS/Entity/EntityConnector.py +70 -0
  201. LOGS/Entity/EntityIterator.py +263 -0
  202. LOGS/Entity/EntityMinimal.py +141 -0
  203. LOGS/Entity/EntityMinimalWithIntId.py +36 -0
  204. LOGS/Entity/EntityMinimalWithStrId.py +36 -0
  205. LOGS/Entity/EntityMinimalWithType.py +47 -0
  206. LOGS/Entity/EntityRequestParameter.py +104 -0
  207. LOGS/Entity/EntitySortBy.py +69 -0
  208. LOGS/Entity/EntityWithIntId.py +26 -0
  209. LOGS/Entity/EntityWithStrId.py +26 -0
  210. LOGS/Entity/IGenericEntityOrderBy.py +55 -0
  211. LOGS/Entity/IdIterator.py +207 -0
  212. LOGS/Entity/SerializableContent.py +834 -0
  213. LOGS/Entity/__init__.py +23 -0
  214. LOGS/Interfaces/ICustomFieldValue.py +92 -0
  215. LOGS/Interfaces/ICustomSectionValue.py +161 -0
  216. LOGS/Interfaces/ICustomTypeValue.py +152 -0
  217. LOGS/Interfaces/ICustomValue.py +28 -0
  218. LOGS/Interfaces/IEntityInterface.py +7 -0
  219. LOGS/Interfaces/IEntryRecord.py +57 -0
  220. LOGS/Interfaces/IHierarchicalEntity.py +41 -0
  221. LOGS/Interfaces/IHierarchyType.py +63 -0
  222. LOGS/Interfaces/ILockableEntity.py +52 -0
  223. LOGS/Interfaces/IModificationRecord.py +56 -0
  224. LOGS/Interfaces/INamedEntity.py +25 -0
  225. LOGS/Interfaces/IOwnedEntity.py +27 -0
  226. LOGS/Interfaces/IPaginationRequest.py +11 -0
  227. LOGS/Interfaces/IPermissionedEntity.py +72 -0
  228. LOGS/Interfaces/IProjectBased.py +27 -0
  229. LOGS/Interfaces/ISessionedEntity.py +59 -0
  230. LOGS/Interfaces/ISignableEntity.py +49 -0
  231. LOGS/Interfaces/ISoftDeletable.py +28 -0
  232. LOGS/Interfaces/ITypedEntity.py +129 -0
  233. LOGS/Interfaces/IUniqueEntity.py +61 -0
  234. LOGS/Interfaces/IVersionedEntity.py +39 -0
  235. LOGS/Interfaces/__init__.py +7 -0
  236. LOGS/LOGS.py +1436 -0
  237. LOGS/LOGSConnection.py +647 -0
  238. LOGS/LOGSOptions.py +11 -0
  239. LOGS/Parameters/Color.py +92 -0
  240. LOGS/Parameters/ParameterBase.py +55 -0
  241. LOGS/Parameters/ParameterConverter.py +24 -0
  242. LOGS/Parameters/ParameterElement.py +99 -0
  243. LOGS/Parameters/ParameterList.py +52 -0
  244. LOGS/Parameters/ParameterTable.py +64 -0
  245. LOGS/Parameters/__init__.py +13 -0
  246. LOGS/ServerMetaData.py +120 -0
  247. LOGS/__init__.py +12 -0
  248. logs_py-4.0.7.dist-info/METADATA +51 -0
  249. logs_py-4.0.7.dist-info/RECORD +251 -0
  250. logs_py-4.0.7.dist-info/WHEEL +5 -0
  251. logs_py-4.0.7.dist-info/top_level.txt +1 -0
@@ -0,0 +1,248 @@
1
+ import os
2
+ from enum import Enum
3
+ from time import sleep, time
4
+ from typing import Any, Callable, Dict, List, Optional, cast
5
+
6
+ from LOGS.Auxiliary.Exceptions import (
7
+ EntityFetchingException,
8
+ LOGSException,
9
+ UnfinishedConversionException,
10
+ )
11
+ from LOGS.Auxiliary.Tools import Tools
12
+ from LOGS.Converter.ConverterParameter import ParameterType
13
+ from LOGS.Entities.ParserLog import ParserLog
14
+ from LOGS.Entity import Entity
15
+ from LOGS.Entity.ConnectedEntity import ConnectedEntity
16
+ from LOGS.Entity.SerializableContent import SerializableClass
17
+ from LOGS.LOGSConnection import ResponseTypes
18
+
19
+
20
+ class ConversionState(Enum):
21
+ Successful = "Successful"
22
+ Failed = "Failed"
23
+ Waiting = "Waiting"
24
+
25
+
26
+ class ConversionFile(SerializableClass):
27
+ path: Optional[str] = None
28
+ size: Optional[int] = None
29
+
30
+
31
+ class DatasetConversionZipReadModel(SerializableClass):
32
+ size: Optional[int] = None
33
+ id: Optional[str] = None
34
+ url: Optional[str] = None
35
+
36
+
37
+ class ConverterParameterEntry(SerializableClass):
38
+ id: Optional[str] = None
39
+ value: Optional[Any] = None
40
+ type: Optional[ParameterType] = None
41
+
42
+
43
+ class ConversionLogModel(ParserLog):
44
+ pass
45
+
46
+
47
+ class Conversion(ConnectedEntity):
48
+ _datasetId: Optional[int] = None
49
+ _datasetFormat: Optional[str] = None
50
+ _exportFormat: Optional[str] = None
51
+ _files: Optional[List[ConversionFile]] = None
52
+ _logs: Optional[List[ConversionLogModel]] = None
53
+ _output: Optional[str] = None
54
+ _state: Optional[ConversionState] = None
55
+ _zip: Optional[DatasetConversionZipReadModel] = None
56
+ _inputParameters: Optional[List[ConverterParameterEntry]] = None
57
+
58
+ _payload: Dict[str, Any] = {}
59
+ _parentEntity: Optional[Entity] = None
60
+
61
+ def download(
62
+ self,
63
+ directory: Optional[str] = None,
64
+ fileName: Optional[str] = None,
65
+ overwrite=False,
66
+ ):
67
+ connection, _ = self._getConnectionData()
68
+
69
+ if self.state == ConversionState.Waiting:
70
+ raise UnfinishedConversionException(self)
71
+
72
+ if self.state == ConversionState.Failed:
73
+ raise LOGSException(
74
+ f"Conversion for dataset {self.datasetId} from format '{self.datasetFormat}' to format '{self.exportFormat}' failed. Check logs for more information."
75
+ )
76
+
77
+ if (
78
+ self.zip is None
79
+ or self.zip.size is None
80
+ or self.zip.id is None
81
+ or self.zip.url is None
82
+ ):
83
+ raise LOGSException(
84
+ f"Conversion for dataset {self.datasetId} from format '{self.datasetFormat}' to format '{self.exportFormat}' did not result in any data."
85
+ )
86
+
87
+ if not directory:
88
+ directory = os.curdir
89
+
90
+ if not fileName:
91
+ fileName = f"dataset_{self.datasetId}_{self.zip.id}.zip"
92
+
93
+ path = os.path.join(directory, Tools.sanitizeFileName(fileName=fileName))
94
+
95
+ if overwrite:
96
+ if os.path.exists(path) and not os.path.isfile(path):
97
+ raise LOGSException("Path %a is not a file" % path)
98
+ else:
99
+ if os.path.exists(path):
100
+ raise LOGSException("File %a already exists" % path)
101
+
102
+ data, responseError = connection.getUrl(
103
+ self.zip.url, responseType=ResponseTypes.RAW
104
+ )
105
+
106
+ if responseError:
107
+ raise LOGSException(
108
+ f"Could not fetch conversion result for dataset {self.datasetId} from format '{self.datasetFormat}' to format '{self.exportFormat}'.",
109
+ responseError=responseError,
110
+ )
111
+
112
+ with open(path, mode="wb") as localFile:
113
+ localFile.write(cast(bytes, data))
114
+
115
+ return path
116
+
117
+ def _reloadOnWaiting(self, connection, endpoint):
118
+ if self.state != ConversionState.Waiting:
119
+ return
120
+ data, responseError = connection.postEndpoint(endpoint, data=self._payload)
121
+ if responseError:
122
+ raise EntityFetchingException(
123
+ entity=self._parentEntity, responseError=responseError
124
+ )
125
+ self.fromDict(data)
126
+
127
+ def awaitResult(self):
128
+ connection, endpoint = self._getConnectionData()
129
+ if self.state != ConversionState.Waiting:
130
+ return
131
+
132
+ while self.state == ConversionState.Waiting:
133
+ sleep(0.5)
134
+ # print("request...")
135
+
136
+ self._reloadOnWaiting(connection, endpoint)
137
+
138
+ # print("... done", self.state)
139
+
140
+ @classmethod
141
+ def awaitAllResults(
142
+ cls,
143
+ conversions: List["Conversion"],
144
+ timeout=600,
145
+ stateChangeHook: Optional[Callable[[int], None]] = None,
146
+ ):
147
+ l = [c for c in conversions if c is not None]
148
+
149
+ connectionList = []
150
+ for i, c in enumerate(l):
151
+ connection, endpoint = c._getConnectionData()
152
+ connectionList.append((c, connection, endpoint))
153
+
154
+ count = sum(
155
+ [1 for c in connectionList if c[0].state != ConversionState.Waiting]
156
+ )
157
+ if stateChangeHook:
158
+ stateChangeHook(len(connectionList) - count)
159
+
160
+ start = time()
161
+ while count < len(connectionList) and time() - start < timeout:
162
+ oldCount = count
163
+ count = 0
164
+ for c in connectionList:
165
+ if c[0].state != ConversionState.Waiting:
166
+ count += 1
167
+ continue
168
+ c[0]._reloadOnWaiting(c[1], c[2])
169
+ if stateChangeHook and oldCount != count:
170
+ stateChangeHook(len(connectionList) - count)
171
+ # print(f"waiting for {len(connectionList) -count} jobs")
172
+ sleep(0.5)
173
+
174
+ @property
175
+ def datasetId(self) -> Optional[int]:
176
+ return self._datasetId
177
+
178
+ @datasetId.setter
179
+ def datasetId(self, value):
180
+ self._datasetId = self.checkAndConvertNullable(value, int, "datasetId")
181
+
182
+ @property
183
+ def datasetFormat(self) -> Optional[str]:
184
+ return self._datasetFormat
185
+
186
+ @datasetFormat.setter
187
+ def datasetFormat(self, value):
188
+ self._datasetFormat = self.checkAndConvertNullable(value, str, "datasetFormat")
189
+
190
+ @property
191
+ def exportFormat(self) -> Optional[str]:
192
+ return self._exportFormat
193
+
194
+ @exportFormat.setter
195
+ def exportFormat(self, value):
196
+ self._exportFormat = self.checkAndConvertNullable(value, str, "exportFormat")
197
+
198
+ @property
199
+ def files(self) -> Optional[List[ConversionFile]]:
200
+ return self._files
201
+
202
+ @files.setter
203
+ def files(self, value):
204
+ self._files = self.checkListAndConvertNullable(value, ConversionFile, "files")
205
+
206
+ @property
207
+ def logs(self) -> Optional[List[ConversionLogModel]]:
208
+ return self._logs
209
+
210
+ @logs.setter
211
+ def logs(self, value):
212
+ self._logs = self.checkListAndConvertNullable(value, ConversionLogModel, "logs")
213
+
214
+ @property
215
+ def output(self) -> Optional[str]:
216
+ return self._output
217
+
218
+ @output.setter
219
+ def output(self, value):
220
+ self._output = self.checkAndConvertNullable(value, str, "output")
221
+
222
+ @property
223
+ def state(self) -> Optional[ConversionState]:
224
+ return self._state
225
+
226
+ @state.setter
227
+ def state(self, value):
228
+ self._state = self.checkAndConvertNullable(value, ConversionState, "state")
229
+
230
+ @property
231
+ def zip(self) -> Optional[DatasetConversionZipReadModel]:
232
+ return self._zip
233
+
234
+ @zip.setter
235
+ def zip(self, value):
236
+ self._zip = self.checkAndConvertNullable(
237
+ value, DatasetConversionZipReadModel, "zip"
238
+ )
239
+
240
+ @property
241
+ def inputParameters(self) -> Optional[List[ConverterParameterEntry]]:
242
+ return self._inputParameters
243
+
244
+ @inputParameters.setter
245
+ def inputParameters(self, value):
246
+ self._inputParameters = self.checkListAndConvertNullable(
247
+ value, ConverterParameterEntry, "inputParameters"
248
+ )
@@ -0,0 +1,96 @@
1
+ from typing import Any, Dict, List, Optional
2
+
3
+ from LOGS.Auxiliary import Tools
4
+ from LOGS.Converter.ConverterParameter import IConverterParameter
5
+ from LOGS.Converter.ExportParameters import ExportParameters
6
+ from LOGS.Entity.SerializableContent import SerializableContent
7
+
8
+
9
+ class Converter(SerializableContent):
10
+ _formatId: Optional[str] = None
11
+ _exportId: Optional[str] = None
12
+ _version: Optional[str] = None
13
+ _name: Optional[str] = None
14
+ _id: Optional[str] = None
15
+ _parameters: Optional[List[IConverterParameter]] = None
16
+
17
+ def __init__(self, ref=None):
18
+ t = type(self)
19
+
20
+ self._noSerialize += [
21
+ t.parameters.fget.__name__, # type: ignore
22
+ ]
23
+
24
+ super().__init__(ref)
25
+
26
+ def __str__(self):
27
+ return Tools.ObjectToString(self)
28
+
29
+ @property
30
+ def formatId(self) -> Optional[str]:
31
+ return self._formatId
32
+
33
+ @formatId.setter
34
+ def formatId(self, value):
35
+ self._formatId = self.checkAndConvertNullable(value, str, "formatId")
36
+
37
+ @property
38
+ def exportId(self) -> Optional[str]:
39
+ return self._exportId
40
+
41
+ @exportId.setter
42
+ def exportId(self, value):
43
+ self._exportId = self.checkAndConvertNullable(value, str, "exportId")
44
+
45
+ @property
46
+ def version(self) -> Optional[str]:
47
+ return self._version
48
+
49
+ @version.setter
50
+ def version(self, value):
51
+ self._version = self.checkAndConvertNullable(value, str, "version")
52
+
53
+ @property
54
+ def name(self) -> Optional[str]:
55
+ return self._name
56
+
57
+ @name.setter
58
+ def name(self, value):
59
+ self._name = self.checkAndConvertNullable(value, str, "name")
60
+
61
+ @property
62
+ def id(self) -> Optional[str]:
63
+ return self._id
64
+
65
+ @id.setter
66
+ def id(self, value):
67
+ self._id = self.checkAndConvertNullable(value, str, "id")
68
+
69
+ @property
70
+ def requestParameter(self) -> Optional[ExportParameters]:
71
+ if self.parameters is None:
72
+ return None
73
+
74
+ p: Dict[str, Any] = {p.id: None for p in self.parameters if p.id}
75
+ p["_parentId"] = self.id
76
+ return ExportParameters(
77
+ ref=p,
78
+ types={
79
+ p.id: IConverterParameter.TypeMapper(p.type)
80
+ for p in self.parameters
81
+ if p.id
82
+ },
83
+ )
84
+
85
+ @property
86
+ def parameters(self) -> Optional[List[IConverterParameter]]:
87
+ return self._parameters
88
+
89
+ @parameters.setter
90
+ def parameters(self, value):
91
+ self._parameters = self.checkListAndConvertNullable(
92
+ value,
93
+ fieldType=IConverterParameter,
94
+ converter=IConverterParameter.GetParameterFromDict,
95
+ fieldName="parameters",
96
+ )
@@ -0,0 +1,88 @@
1
+ from enum import Enum
2
+ from typing import Optional, Union
3
+
4
+ from LOGS.Entity.SerializableContent import SerializableClass
5
+
6
+
7
+ class ParameterType(Enum):
8
+ Integer = "Integer"
9
+ String = "String"
10
+ Boolean = "Boolean"
11
+ Float = "Float"
12
+
13
+
14
+ class IConverterParameter(SerializableClass):
15
+ name: Optional[str] = None
16
+ id: Optional[str] = None
17
+ description: Optional[str] = None
18
+ required: Optional[bool] = None
19
+ hasDefault: Optional[bool] = None
20
+ identifier: Optional[str] = None
21
+
22
+ @classmethod
23
+ def TypeMapper(cls, t: Union[ParameterType, str]):
24
+ if t == ParameterType.Integer:
25
+ return int
26
+ if t == ParameterType.String:
27
+ return str
28
+ if t == ParameterType.Boolean:
29
+ return bool
30
+ if t == ParameterType.Float:
31
+ return float
32
+ raise Exception("Unknown parameter type '%s'" % t)
33
+
34
+ @classmethod
35
+ def GetParameterFromDict(cls, data: dict):
36
+ if not isinstance(data, dict) or "type" not in data:
37
+ raise Exception(f"Export parameter type not specified.")
38
+
39
+ type = data["type"]
40
+ if type not in ParameterType.__members__:
41
+ raise Exception(
42
+ f"Unknown export parameter type '{type}' not found in parameter data"
43
+ )
44
+
45
+ type = ParameterType.__members__[type]
46
+
47
+ if type == ParameterType.Integer:
48
+ return ConverterIntegerParameter(data)
49
+ if type == ParameterType.String:
50
+ return ConverterStringParameter(data)
51
+ if type == ParameterType.Boolean:
52
+ return ConverterBooleanParameter(data)
53
+ if type == ParameterType.Float:
54
+ return ConverterFloatParameter(data)
55
+
56
+ raise Exception(
57
+ f"Unknown export parameter type '{type}' not found in parameter data"
58
+ )
59
+
60
+ @property
61
+ def type(self) -> ParameterType:
62
+ raise NotImplementedError(
63
+ f"{type(self).__name__} is an abstract class. Please implement the 'type' property."
64
+ )
65
+
66
+
67
+ class ConverterIntegerParameter(IConverterParameter):
68
+ @property
69
+ def type(self) -> ParameterType:
70
+ return ParameterType.Integer
71
+
72
+
73
+ class ConverterStringParameter(IConverterParameter):
74
+ @property
75
+ def type(self) -> ParameterType:
76
+ return ParameterType.String
77
+
78
+
79
+ class ConverterBooleanParameter(IConverterParameter):
80
+ @property
81
+ def type(self) -> ParameterType:
82
+ return ParameterType.Boolean
83
+
84
+
85
+ class ConverterFloatParameter(IConverterParameter):
86
+ @property
87
+ def type(self) -> ParameterType:
88
+ return ParameterType.Float
@@ -0,0 +1,58 @@
1
+ from datetime import datetime
2
+ from typing import Any, Dict, Optional, cast
3
+
4
+ from LOGS.Auxiliary.Tools import Tools
5
+ from LOGS.Entity.SerializableContent import SerializableContent
6
+
7
+
8
+ class DateTimeRange(SerializableContent):
9
+ """Represents a range of two datetime values"""
10
+
11
+ _start: Optional[datetime] = None
12
+ _end: Optional[datetime] = None
13
+
14
+ def __init__(
15
+ self, ref=None, start: Optional[datetime] = None, end: Optional[datetime] = None
16
+ ):
17
+ if isinstance(ref, list):
18
+ ref = {
19
+ "start": (ref[0] if len(ref) > 0 else None),
20
+ "end": (ref[1] if len(ref) > 1 else None),
21
+ }
22
+ super().__init__(ref=ref)
23
+ if start is not None:
24
+ self.start = start
25
+ if end is not None:
26
+ self.end = end
27
+
28
+ def toDict(self) -> Dict[str, Any]:
29
+ return cast(
30
+ Dict[str, Any],
31
+ [
32
+ Tools.datetimeToUTCString(self.start),
33
+ Tools.datetimeToUTCString(self.end),
34
+ ],
35
+ )
36
+
37
+ def __str__(self) -> str:
38
+ return f"<DateTimeRange [{self.start}, {self.end}]>"
39
+
40
+ @property
41
+ def start(self) -> Optional[datetime]:
42
+ return self._start
43
+
44
+ @start.setter
45
+ def start(self, value: Optional[datetime]):
46
+ self._start = Tools.checkAndConvert(
47
+ value, datetime, "DateTimeRange.start", allowNone=True
48
+ )
49
+
50
+ @property
51
+ def end(self) -> Optional[datetime]:
52
+ return self._end
53
+
54
+ @end.setter
55
+ def end(self, value: Optional[datetime]):
56
+ self._end = Tools.checkAndConvert(
57
+ value, datetime, "DateTimeRange.end", allowNone=True
58
+ )
@@ -0,0 +1,89 @@
1
+ from typing import Any, Dict, Optional
2
+
3
+ from LOGS.Auxiliary.Tools import Tools
4
+ from LOGS.Entity.SerializableContent import SerializableClass
5
+
6
+
7
+ class ExportParameters(SerializableClass):
8
+
9
+ def __init__(
10
+ self,
11
+ ref=None,
12
+ types: Optional[Dict[str, type]] = None,
13
+ ):
14
+ self._lock = False
15
+ if types is not None:
16
+ if not isinstance(types, dict):
17
+ raise Exception("type must be a dictionary")
18
+ for k, v in types.items():
19
+ if not isinstance(v, type):
20
+ raise Exception(
21
+ f"Invalid type for key '{k}'. (Expected '{type.__name__}' got '{type(v).__name__}')"
22
+ )
23
+ else:
24
+ types = {}
25
+
26
+ self._typeMapping: Dict[str, type] = {}
27
+ if isinstance(ref, dict):
28
+ if "_parentId" in ref:
29
+ self._parentId: Optional[str] = str(ref["_parentId"])
30
+ del ref["_parentId"]
31
+ else:
32
+ self._parentId = None
33
+
34
+ self._includeNone = True
35
+ for k in ref.keys():
36
+ setattr(self, k, ref[k])
37
+ if k in types:
38
+ self._typeMapping[k] = types[k]
39
+ super().__init__(ref)
40
+ self._lock = True
41
+
42
+ def fromDict(self, ref) -> None:
43
+ if getattr(self, "_lock", False):
44
+ if isinstance(ref, dict):
45
+ if "parameters" in ref and isinstance(ref["parameters"], list):
46
+ for p in ref["parameters"]:
47
+ if "id" in p and "value" in p:
48
+ setattr(self, p["id"], p["value"])
49
+ for k, v in ref.items():
50
+ setattr(self, k, v)
51
+ return super().fromDict(ref)
52
+
53
+ def toDict(self) -> Dict[str, Any]:
54
+ l = [
55
+ {"id": k, "value": getattr(self, k)}
56
+ for k in self.__dict__
57
+ if k[0] != "_" and getattr(self, k) is not None
58
+ ]
59
+ if l:
60
+ return {"parameters": l}
61
+ return {}
62
+
63
+ def __repr__(self):
64
+ fields = [
65
+ f"{k}{':' + self._typeMapping[k].__name__ if k in self._typeMapping else ''}={v}"
66
+ for k, v in self.toDict().items()
67
+ ]
68
+ return f'{self.identifier}({", ".join(fields)})'
69
+
70
+ def __setattr__(self, name: str, value: Any) -> None:
71
+ if getattr(self, "_lock", False):
72
+ if name not in self._typeMapping:
73
+ raise Exception(f"Unknown field '{self.identifier}.{name}'")
74
+
75
+ if name in self._typeMapping:
76
+ value = Tools.checkAndConvert(
77
+ value,
78
+ self._typeMapping[name],
79
+ f"{self.identifier}.{name}",
80
+ allowNone=True,
81
+ )
82
+ return super().__setattr__(name, value)
83
+
84
+ @property
85
+ def identifier(self):
86
+ return f"{self.__class__.__name__}{'<' + self._parentId + '>' if self._parentId else ''}"
87
+
88
+ def __str__(self):
89
+ return self.__repr__()
@@ -0,0 +1,13 @@
1
+ """
2
+ This package is written for the LOGS Repository.
3
+
4
+ It's objects can be used to write your own dataset parser.
5
+
6
+ License:
7
+ Permission to use this libraray and all of its contents is
8
+ strictly permitted to the Signals Company.
9
+ """
10
+
11
+ from .Conversion import *
12
+ from .Converter import *
13
+ from .ConverterParameter import *
@@ -0,0 +1,84 @@
1
+ from typing import TYPE_CHECKING, List, Optional, Sequence
2
+
3
+ from LOGS.Auxiliary.Constants import Constants
4
+ from LOGS.Auxiliary.Decorators import Endpoint, UiEndpoint
5
+ from LOGS.Auxiliary.Exceptions import LOGSException
6
+ from LOGS.Entities.DatasetBase import DatasetBase
7
+ from LOGS.Entities.DatasetModels import ViewableEntityTypes
8
+ from LOGS.Entities.FileEntry import FileEntry
9
+ from LOGS.Interfaces.IEntryRecord import IEntryRecord
10
+ from LOGS.Interfaces.IModificationRecord import IModificationRecord
11
+ from LOGS.Interfaces.IUniqueEntity import IUniqueEntity
12
+ from LOGS.LOGSConnection import LOGSConnection
13
+
14
+ if TYPE_CHECKING:
15
+ pass
16
+
17
+
18
+ @Endpoint("datasets")
19
+ @UiEndpoint("#data")
20
+ class Attachment(
21
+ DatasetBase,
22
+ IUniqueEntity,
23
+ IEntryRecord,
24
+ IModificationRecord,
25
+ ):
26
+ _viewableEntityTypes: List[ViewableEntityTypes] = [ViewableEntityTypes.CustomField]
27
+ _isViewableEntity: bool = True
28
+
29
+ def __init__(
30
+ self,
31
+ ref=None,
32
+ id: Optional[int] = None,
33
+ connection: Optional[LOGSConnection] = None,
34
+ files: Optional[Sequence[Constants.FILE_TYPE]] = None,
35
+ pathPrefixToStrip: Optional[str] = None,
36
+ pathPrefixToAdd: Optional[str] = None,
37
+ ):
38
+ from LOGS.Entities.DataFormatMinimal import DataFormatMinimal
39
+
40
+ super().__init__(ref=ref, id=id, connection=connection)
41
+
42
+ t = type(self)
43
+ self._noSerialize += [
44
+ t.parserLogs.fget.__name__, # type: ignore
45
+ ]
46
+ self._format = DataFormatMinimal(
47
+ id="doc_multi", name="Attachment format", connection=self._getConnection()
48
+ )
49
+
50
+ if files:
51
+ if not self._format or not self._format.id:
52
+ raise LOGSException(
53
+ "Cannot create %s object from files parameter without a format"
54
+ % type(self).__name__
55
+ )
56
+
57
+ self._files = FileEntry.entriesFromFiles(files)
58
+ if self._files is not None:
59
+ for file in self._files:
60
+ if pathPrefixToStrip and file.path:
61
+ file.modifyPathPrefix(pathPrefixToStrip, pathPrefixToAdd)
62
+
63
+ def fromDict(self, ref) -> None:
64
+ if isinstance(ref, dict):
65
+
66
+ infoFields = [
67
+ "parserLogs",
68
+ "parsingState",
69
+ ]
70
+
71
+ self._noInfo = not all(f in ref for f in infoFields)
72
+
73
+ info = {}
74
+ for field in infoFields:
75
+ if field in ref:
76
+ info[field] = ref[field]
77
+ del ref[field]
78
+
79
+ super().fromDict(ref=ref)
80
+ self._setInfo(info)
81
+
82
+ def fetchFull(self):
83
+ self.fetchInfo()
84
+ self.fetchZipSize()
@@ -0,0 +1,8 @@
1
+ from LOGS.Auxiliary.Decorators import FullModel
2
+ from LOGS.Entities.Attachment import Attachment
3
+ from LOGS.Entity.EntityMinimalWithIntId import EntityMinimalWithIntId
4
+
5
+
6
+ @FullModel(Attachment)
7
+ class AttachmentMinimal(EntityMinimalWithIntId[Attachment]):
8
+ pass