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,263 @@
1
+ import dataclasses
2
+ from typing import Any, Generic, List, Optional, Type, TypeVar, cast
3
+
4
+ from LOGS.Auxiliary.Constants import Constants
5
+ from LOGS.Auxiliary.Exceptions import LOGSException
6
+ from LOGS.Auxiliary.Tools import Tools
7
+ from LOGS.Entity.Entity import Entity
8
+ from LOGS.Entity.EntityConnector import EntityConnector
9
+ from LOGS.Entity.EntityRequestParameter import EntityRequestParameter
10
+ from LOGS.Entity.IdIterator import EmptyIdIterator, IdIterator
11
+ from LOGS.LOGSConnection import RESPONSE_TYPES, LOGSConnection, ResponseTypes
12
+
13
+ # SELF = TypeVar("SELF", bound="EntityConnector")
14
+
15
+ _ENTITY = TypeVar("_ENTITY", bound=Entity)
16
+ _REQUEST = TypeVar("_REQUEST", bound=EntityRequestParameter)
17
+
18
+
19
+ class EntityIterator(Generic[_ENTITY, _REQUEST], EntityConnector[_ENTITY]):
20
+ """Represents a connected LOGS entity iterator"""
21
+
22
+ _firstUrl: Optional[str] = None
23
+ _entityIterator: int
24
+ _currentResults: Optional[RESPONSE_TYPES]
25
+ _generatorType: Optional[Type[_ENTITY]] = None
26
+ _parameterType: Optional[Type[_REQUEST]] = None
27
+
28
+ _parameters: _REQUEST
29
+ _responseType: ResponseTypes = ResponseTypes.JSON
30
+ _includeUrl: bool = True
31
+ _connection: Optional[LOGSConnection]
32
+ _count: Optional[int]
33
+
34
+ def __init__(
35
+ self,
36
+ connection: Optional[LOGSConnection],
37
+ parameters: Optional[_REQUEST] = None,
38
+ ):
39
+ super().__init__(connection=connection)
40
+
41
+ if not self._parameterType:
42
+ raise NotImplementedError(
43
+ "Entity connection cannot be initialized without the request 'parameterType' field in class %a"
44
+ % type(self).__name__
45
+ )
46
+
47
+ if not isinstance(self._parameterType, type):
48
+ raise NotImplementedError(
49
+ "The field 'parameterType' must be a 'type' got %a in class %a"
50
+ % (type(self._parameterType), type(self).__name__)
51
+ )
52
+
53
+ if parameters and not isinstance(parameters, self._parameterType):
54
+ raise LOGSException(
55
+ "Parameter for iterator %a must be of type %a. (Got %a)"
56
+ % (
57
+ type(self).__name__,
58
+ self._parameterType.__name__,
59
+ type(parameters).__name__,
60
+ )
61
+ )
62
+
63
+ self._parameters = Tools.checkAndConvert(
64
+ parameters, self._parameterType, "parameters", initOnNone=True
65
+ )
66
+
67
+ self._entityIterator = 0
68
+ self._currentResults = None
69
+ self._count = None
70
+
71
+ def __iter__(self):
72
+ self._initEntityIterator()
73
+ return self
74
+
75
+ def __next__(self) -> _ENTITY:
76
+ from LOGS.Auxiliary.CustomEntityClassGenerator import CustomEntityClassGenerator
77
+ from LOGS.Entity.ConnectedEntity import ConnectedEntity
78
+ from LOGS.Interfaces.ITypedEntity import ITypedEntity
79
+
80
+ if not self._generatorType:
81
+ raise NotImplementedError(
82
+ "Iterator cannot generate items without a specified 'generatorType' field in class %a"
83
+ % type(self).__name__
84
+ )
85
+
86
+ if issubclass(self._generatorType, ConnectedEntity):
87
+ next = cast(Any, self._generatorType)(
88
+ self._getNextEntity(), connection=self._connection
89
+ )
90
+ else:
91
+ next = cast(Any, self._generatorType)(self._getNextEntity())
92
+
93
+ if issubclass(self._generatorType, ITypedEntity):
94
+ next = CustomEntityClassGenerator.convertFromUntyped(
95
+ next, limitToEntityType=self._generatorType
96
+ )
97
+
98
+ return next
99
+
100
+ def _getNextPage(self, result):
101
+ if not self._connection:
102
+ raise LOGSException("Connection of %a is not defined" % type(self).__name__)
103
+
104
+ if "hasNext" not in result or not result["hasNext"]:
105
+ return None, None
106
+
107
+ url = result["url"]
108
+
109
+ page = 1
110
+ if "page" in result:
111
+ page = int(result["page"])
112
+ elif self._parameters.page:
113
+ page = self._parameters.page
114
+ self._parameters.page = page + 1
115
+ return self._connection.postUrl(
116
+ url=url,
117
+ data=self._parameters.toDict(),
118
+ responseType=self._responseType,
119
+ includeUrl=self._includeUrl,
120
+ )
121
+
122
+ # ### code for using get ###
123
+ # o = urlparse(result["url"])
124
+ # params = parse_qs(o.query)
125
+ # params = {k: v[0] if isinstance(v, list) else v for k, v in params.items()}
126
+
127
+ # page = 1
128
+ # if "page" in params:
129
+ # page = int(params["page"])
130
+ # params["page"] = page + 1
131
+
132
+ # urlList = list(o)
133
+ # urlList[4] = None
134
+ # url = cast(str, urlunparse(urlList))
135
+
136
+ # return self._connection.getUrl(
137
+ # url,
138
+ # parameters=params,
139
+ # responseType=self._responseType,
140
+ # includeUrl=self._includeUrl,
141
+ # )
142
+
143
+ def _initEntityIterator(self):
144
+ url = self.getBaseUrl()
145
+ self._entityIterator = 0
146
+
147
+ if not self._connection:
148
+ raise LOGSException(
149
+ "Entity connector %a is not connected" % type(self).__name__
150
+ )
151
+
152
+ # ### code for using get ###
153
+ # self._currentResults, error = self._connection.getUrl(
154
+ # url=url,
155
+ # parameters=self._parameters.toDict(),
156
+ # responseType=self._responseType,
157
+ # includeUrl=self._includeUrl,
158
+ # )
159
+ tmp = False
160
+ if hasattr(self._parameters, "includeCount"):
161
+ tmp = self._parameters.includeCount
162
+ self._parameters.includeCount = True
163
+
164
+ self._currentResults, responseError = self._connection.postUrl(
165
+ url=url + "/list",
166
+ data=self._parameters.toDict(),
167
+ responseType=self._responseType,
168
+ includeUrl=self._includeUrl,
169
+ )
170
+
171
+ if hasattr(self._parameters, "includeCount"):
172
+ self._parameters.includeCount = tmp
173
+
174
+ if isinstance(self._currentResults, dict) and "count" in self._currentResults:
175
+ self._count = int(self._currentResults["count"])
176
+
177
+ if responseError:
178
+ raise LOGSException(responseError=responseError)
179
+
180
+ def _getNextEntity(self):
181
+ if not isinstance(self._currentResults, dict):
182
+ raise StopIteration
183
+
184
+ results = self._currentResults["results"]
185
+ if self._entityIterator < len(results):
186
+ result = results[self._entityIterator]
187
+ self._entityIterator += 1
188
+ return result
189
+
190
+ self._currentResults, error = self._getNextPage(self._currentResults)
191
+ if error:
192
+ raise Exception("Connection error: %a", error)
193
+ self._entityIterator = 0
194
+
195
+ if (
196
+ not self._currentResults
197
+ or not isinstance(self._currentResults, dict)
198
+ or len(self._currentResults["results"]) < 1
199
+ ):
200
+ raise StopIteration
201
+
202
+ return self._getNextEntity()
203
+
204
+ def split(self, size=20):
205
+ connection, _ = self._getConnectionData()
206
+
207
+ items = iter(self)
208
+ ids = []
209
+ for item in items:
210
+ ids.append(item.id)
211
+ if len(ids) >= size:
212
+ param = dataclasses.replace(self._parameters)
213
+ param.ids = ids
214
+ iterator = type(self)(connection=connection)
215
+ iterator._parameters = param
216
+ yield iterator
217
+ ids = []
218
+ if ids:
219
+ param = dataclasses.replace(self._parameters)
220
+ param.ids = ids
221
+ iterator = type(self)(connection=connection)
222
+ iterator._parameters = param
223
+ yield iterator
224
+
225
+ def ids(self):
226
+ if not self._generatorType:
227
+ return EmptyIdIterator[Constants.ID_TYPE]()
228
+ d = self._generatorType()
229
+ iterator = IdIterator[type(d.id), _REQUEST](connection=self._connection)
230
+ iterator._endpoint = self._endpoint
231
+ iterator._parameters = self._parameters
232
+ iterator._parameterType = self._parameterType
233
+ iterator._generatorType = type(d.id)
234
+ return iterator
235
+
236
+ def first(self):
237
+ i = iter(self)
238
+ try:
239
+ return cast(_ENTITY, next(i))
240
+ except StopIteration:
241
+ return None
242
+
243
+ def toList(self, count: Optional[int] = None):
244
+ if count:
245
+ count = int(count)
246
+ if count < 0:
247
+ raise Exception("Invalid negative count %d" % count)
248
+ result = cast(List[_ENTITY], [])
249
+ num = 0
250
+ for entity in self:
251
+ result.append(entity)
252
+ num += 1
253
+ if num >= count:
254
+ break
255
+ return result
256
+
257
+ return list(self)
258
+
259
+ @property
260
+ def count(self) -> int:
261
+ if self._count is None:
262
+ self._initEntityIterator()
263
+ return self._count if self._count else 0
@@ -0,0 +1,141 @@
1
+ from typing import Generic, Optional, Type, TypeVar, cast
2
+ from uuid import UUID
3
+
4
+ from LOGS.Auxiliary.Exceptions import LOGSException
5
+ from LOGS.Entity.ConnectedEntity import ConnectedEntity
6
+ from LOGS.Entity.Entity import Entity
7
+ from LOGS.LOGSConnection import LOGSConnection
8
+
9
+ _FULL_ENTITY = TypeVar("_FULL_ENTITY", bound=Entity)
10
+ _ID_TYPE = TypeVar("_ID_TYPE", int, str)
11
+
12
+
13
+ class EntityMinimal(Generic[_ID_TYPE, _FULL_ENTITY], ConnectedEntity):
14
+ _id: Optional[_ID_TYPE]
15
+ _name: Optional[str]
16
+ _fullEntityType: Optional[Type[_FULL_ENTITY]] = None
17
+ _uid: Optional[UUID] = None
18
+ _version: Optional[int] = None
19
+ _isDeleted: Optional[bool] = None
20
+ _isLocked: Optional[bool] = None
21
+ _isSigned: Optional[bool] = None
22
+
23
+ def __init__(
24
+ self,
25
+ ref=None,
26
+ id: Optional[_ID_TYPE] = None,
27
+ connection: Optional[LOGSConnection] = None,
28
+ name: Optional[str] = None,
29
+ ):
30
+ """Represents a connected LOGS entity type"""
31
+ self._id = id
32
+ self._name = name
33
+ self._uid = None
34
+ self._version = None
35
+
36
+ if isinstance(ref, Entity):
37
+ self._id = cast(_ID_TYPE, ref.id)
38
+ if hasattr(ref, "name"):
39
+ self._name = getattr(ref, "name")
40
+ ref = None
41
+ super().__init__(ref=ref, connection=connection)
42
+
43
+ def contentToString(self, indentation: int = 1, hideNone: bool = False) -> str:
44
+ return str(self)
45
+
46
+ def __str__(self):
47
+ s = " name:'%s'" % (self.name if self.name else "")
48
+ return "<%s id:%s%s>" % (type(self).__name__, str(self.id), s)
49
+
50
+ def _fetchEntity(self, connection: LOGSConnection):
51
+ from LOGS.Interfaces.ITypedEntity import ITypedEntity
52
+
53
+ if not self._endpoint:
54
+ raise NotImplementedError(
55
+ "Fetching of entity type %a is not implemented."
56
+ % (
57
+ type(self).__name__
58
+ if type(self).__name__ != EntityMinimal.__name__
59
+ else "unknown"
60
+ )
61
+ )
62
+
63
+ if not self._fullEntityType:
64
+ raise LOGSException("Full entity type of %a not set." % type(self).__name__)
65
+
66
+ entity = cast(Type[_FULL_ENTITY], self._fullEntityType)(
67
+ id=self.id, connection=connection
68
+ )
69
+ entity.fetch()
70
+ if isinstance(entity, ITypedEntity):
71
+ entity = entity._getTypedInstance()
72
+
73
+ return entity
74
+
75
+ def fetchFullEntity(self):
76
+ return self._fetchEntity(self._getConnection())
77
+
78
+ @property
79
+ def identifier(self):
80
+ name = self.name
81
+ return "%s(id:%s) %s" % (
82
+ type(self).__name__,
83
+ str(self.id),
84
+ "'" + name + "'" if name else "",
85
+ )
86
+
87
+ @property
88
+ def name(self) -> Optional[str]:
89
+ return self._name
90
+
91
+ @name.setter
92
+ def name(self, value):
93
+ self._name = self.checkAndConvert(value, str, "name", allowNone=True)
94
+
95
+ @property
96
+ def id(self):
97
+ return self._id
98
+
99
+ @id.setter
100
+ def id(self, value):
101
+ self._id = value
102
+
103
+ @property
104
+ def uid(self) -> Optional[UUID]:
105
+ return self._uid
106
+
107
+ @uid.setter
108
+ def uid(self, value):
109
+ self._uid = self.checkAndConvert(value, UUID, "uid", allowNone=True)
110
+
111
+ @property
112
+ def version(self) -> Optional[int]:
113
+ return self._version
114
+
115
+ @version.setter
116
+ def version(self, value):
117
+ self._version = self.checkAndConvert(value, int, "uid", allowNone=True)
118
+
119
+ @property
120
+ def isDeleted(self) -> Optional[bool]:
121
+ return self._isDeleted
122
+
123
+ @isDeleted.setter
124
+ def isDeleted(self, value):
125
+ self._isDeleted = self.checkAndConvert(value, bool, "isDeleted", allowNone=True)
126
+
127
+ @property
128
+ def isLocked(self) -> Optional[bool]:
129
+ return self._isLocked
130
+
131
+ @isLocked.setter
132
+ def isLocked(self, value):
133
+ self._isLocked = self.checkAndConvert(value, bool, "isLocked", allowNone=True)
134
+
135
+ @property
136
+ def isSigned(self) -> Optional[bool]:
137
+ return self._isSigned
138
+
139
+ @isSigned.setter
140
+ def isSigned(self, value):
141
+ self._isSigned = self.checkAndConvert(value, bool, "isSigned", allowNone=True)
@@ -0,0 +1,36 @@
1
+ from typing import TYPE_CHECKING, Generic, Optional, TypeVar
2
+
3
+ from LOGS.Auxiliary.Tools import Tools
4
+ from LOGS.Entity.EntityMinimal import EntityMinimal
5
+ from LOGS.LOGSConnection import LOGSConnection
6
+
7
+ if TYPE_CHECKING:
8
+ from LOGS.Entity.Entity import Entity
9
+
10
+ _FULL_ENTITY = TypeVar("_FULL_ENTITY", bound="Entity")
11
+
12
+
13
+ class EntityMinimalWithIntId(Generic[_FULL_ENTITY], EntityMinimal[int, _FULL_ENTITY]):
14
+ _id: int
15
+
16
+ def __init__(
17
+ self,
18
+ ref=None,
19
+ id: Optional[int] = 0,
20
+ connection: Optional[LOGSConnection] = None,
21
+ name: Optional[str] = None,
22
+ ):
23
+ """Represents a connected LOGS entity type"""
24
+ super().__init__(ref=ref, id=id, name=name, connection=connection)
25
+
26
+ def __str__(self):
27
+ s = " name:'%s'" % (self.name if self.name else "")
28
+ return "<%s id:%s%s>" % (type(self).__name__, str(self.id), s)
29
+
30
+ @property
31
+ def id(self) -> int:
32
+ return self._id
33
+
34
+ @id.setter
35
+ def id(self, value):
36
+ self._id = Tools.checkAndConvert(value, int, "id")
@@ -0,0 +1,36 @@
1
+ from typing import TYPE_CHECKING, Generic, Optional, TypeVar
2
+
3
+ from LOGS.Auxiliary.Tools import Tools
4
+ from LOGS.Entity.EntityMinimal import EntityMinimal
5
+ from LOGS.LOGSConnection import LOGSConnection
6
+
7
+ if TYPE_CHECKING:
8
+ from LOGS.Entity.Entity import Entity
9
+
10
+ _FULL_ENTITY = TypeVar("_FULL_ENTITY", bound="Entity")
11
+
12
+
13
+ class EntityMinimalWithStrId(Generic[_FULL_ENTITY], EntityMinimal[str, _FULL_ENTITY]):
14
+ _id: str
15
+
16
+ def __init__(
17
+ self,
18
+ ref=None,
19
+ id: Optional[str] = "",
20
+ connection: Optional[LOGSConnection] = None,
21
+ name: Optional[str] = None,
22
+ ):
23
+ """Represents a connected LOGS entity type"""
24
+ super().__init__(ref=ref, id=id, name=name, connection=connection)
25
+
26
+ def __str__(self):
27
+ s = " name:'%s'" % (self.name if self.name else "")
28
+ return "<%s id:%s%s>" % (type(self).__name__, str(self.id), s)
29
+
30
+ @property
31
+ def id(self) -> str:
32
+ return self._id
33
+
34
+ @id.setter
35
+ def id(self, value):
36
+ self._id = Tools.checkAndConvert(value, str, "id")
@@ -0,0 +1,47 @@
1
+ from typing import Optional
2
+
3
+ from LOGS.Auxiliary.Constants import Constants
4
+ from LOGS.Auxiliary.Tools import Tools
5
+ from LOGS.Entity.EntityMinimal import EntityMinimal
6
+ from LOGS.Entity.EntityRequestParameter import EntityRequestParameter
7
+ from LOGS.LOGSConnection import LOGSConnection
8
+
9
+
10
+ class EntityMinimalWithType(EntityMinimal):
11
+ _id: int
12
+ _type: str
13
+ _defaultRequestParameter: dict = EntityRequestParameter().toDict()
14
+
15
+ def __init__(
16
+ self,
17
+ ref=None,
18
+ id: Optional[Constants.ID_TYPE] = None,
19
+ connection: Optional[LOGSConnection] = None,
20
+ name: Optional[str] = None,
21
+ type: str = "",
22
+ ):
23
+ """Represents a connected LOGS entity type"""
24
+
25
+ self._type = type
26
+ super().__init__(ref=ref, id=id, name=name, connection=connection)
27
+
28
+ def __str__(self):
29
+ n = " name:'%s'" % (self.name if self.name else "")
30
+ t = " type:'%s'" % (self.type if self.type else "")
31
+ return "<%s id:%s%s%s>" % (type(self).__name__, str(self.id), n, t)
32
+
33
+ @property
34
+ def id(self) -> int:
35
+ return self._id
36
+
37
+ @id.setter
38
+ def id(self, value):
39
+ self._id = Tools.checkAndConvert(value, int, "id")
40
+
41
+ @property
42
+ def type(self) -> str:
43
+ return self._type
44
+
45
+ @type.setter
46
+ def type(self, value):
47
+ self._type = Tools.checkAndConvert(value, str, "type")
@@ -0,0 +1,104 @@
1
+ from dataclasses import dataclass, field
2
+ from typing import (
3
+ Any,
4
+ Callable,
5
+ Generic,
6
+ List,
7
+ Optional,
8
+ Tuple,
9
+ Type,
10
+ TypeVar,
11
+ Union,
12
+ cast,
13
+ )
14
+
15
+ from LOGS.Entity.EntitySortBy import EntitySortBy, SortDirection
16
+ from LOGS.Entity.IGenericEntityOrderBy import (
17
+ IBaseEntityOrderBy,
18
+ IGenericEntitySortingOptions,
19
+ INamedEntitySortingOptions,
20
+ )
21
+ from LOGS.Entity.SerializableContent import SerializableClass
22
+ from LOGS.Interfaces.IPaginationRequest import IPaginationRequest
23
+
24
+
25
+ class DefaultSortingOptions(IGenericEntitySortingOptions, INamedEntitySortingOptions):
26
+ pass
27
+
28
+
29
+ _Sorting = TypeVar("_Sorting", bound=IBaseEntityOrderBy)
30
+
31
+
32
+ @dataclass
33
+ class EntityRequestParameter(Generic[_Sorting], SerializableClass, IPaginationRequest):
34
+ _orderByType: Type[_Sorting] = field(default=cast(Type[_Sorting], None), init=False)
35
+
36
+ _getOrderbyType: Callable[[], Type[_Sorting]] = field(
37
+ default=lambda: cast(Type[_Sorting], None), init=False
38
+ )
39
+
40
+ excludeIds: Optional[Union[List[int], List[str]]] = None
41
+ searchTerm: Optional[str] = None
42
+ ids: Optional[Union[List[int], List[str]]] = None
43
+ includeCount: Optional[bool] = None
44
+ sortBy: Optional[
45
+ Union[
46
+ List[
47
+ Union[
48
+ Tuple[_Sorting, SortDirection],
49
+ Tuple[int, SortDirection],
50
+ _Sorting,
51
+ int,
52
+ ]
53
+ ],
54
+ _Sorting,
55
+ int,
56
+ ]
57
+ ] = None
58
+
59
+ def __post_init__(self):
60
+ orderByType = self.__class__._orderByType
61
+ if type(self) is not EntityRequestParameter and not orderByType:
62
+ raise NotImplementedError(
63
+ f"{self.__class__.__name__} does not define an order type."
64
+ )
65
+
66
+ if self.sortBy:
67
+ if not isinstance(self.sortBy, list):
68
+ self.sortBy = [self.sortBy]
69
+
70
+ convertedSortBy: List[EntitySortBy[_Sorting]] = []
71
+ for i, t in enumerate(self.sortBy):
72
+ if not isinstance(t, tuple):
73
+ t = (t, SortDirection.ASC)
74
+
75
+ if isinstance(t[0], int):
76
+ customFieldId = t[0]
77
+ property = orderByType.CUSTOM_FIELD
78
+ elif isinstance(t[0], (orderByType, str)):
79
+ customFieldId = None
80
+ property = self.checkAndConvert(
81
+ t[0], orderByType, f"sortBy[{i}][0]"
82
+ )
83
+ else:
84
+ raise TypeError(
85
+ f"Invalid type '{type(t[0]).__name__}' for sortBy[{i}][0]. (Expected int or {orderByType.__name__})"
86
+ )
87
+
88
+ if len(t) > 1:
89
+ direction = self.checkAndConvert(
90
+ t[1], SortDirection, f"sortBy[{i}][1]"
91
+ )
92
+ else:
93
+ direction = SortDirection.ASC
94
+
95
+ convertedSortBy.append(
96
+ EntitySortBy[_Sorting](
97
+ orderByType=orderByType,
98
+ property=property,
99
+ sortDirection=direction,
100
+ customFieldId=customFieldId,
101
+ )
102
+ )
103
+
104
+ self.sortBy = cast(Any, convertedSortBy)
@@ -0,0 +1,69 @@
1
+ from enum import Enum
2
+ from typing import Generic, Optional, Type, TypeVar, cast
3
+
4
+ from LOGS.Entity.IGenericEntityOrderBy import IBaseEntityOrderBy
5
+ from LOGS.Entity.SerializableContent import SerializableContent
6
+
7
+ _ORDER = TypeVar("_ORDER", bound=IBaseEntityOrderBy)
8
+
9
+
10
+ class SortDirection(Enum):
11
+ ASC = "ASC"
12
+ DESC = "DESC"
13
+
14
+
15
+ _builtInProperty = property # this avoids a name conflict between the @property decorator and field property
16
+
17
+
18
+ class EntitySortBy(Generic[_ORDER], SerializableContent):
19
+ _orderByType: Type[_ORDER] = cast(Type[_ORDER], None)
20
+
21
+ _property: Optional[_ORDER] = None
22
+ _sortDirection: SortDirection = SortDirection.ASC
23
+ _customFieldId: Optional[int] = None
24
+
25
+ def __init__(
26
+ self,
27
+ orderByType: Type[_ORDER],
28
+ property: _ORDER,
29
+ sortDirection: SortDirection = SortDirection.ASC,
30
+ customFieldId: Optional[int] = None,
31
+ ):
32
+ super().__init__()
33
+
34
+ self._orderByType = orderByType
35
+ if not self._orderByType:
36
+ raise NotImplementedError(
37
+ f"{self.__class__.__name__} does not define an order type."
38
+ )
39
+
40
+ self.property = property
41
+ self.sortDirection = sortDirection
42
+ self.customFieldId = customFieldId
43
+
44
+ @_builtInProperty
45
+ def property(self) -> Optional[_ORDER]:
46
+ return self._property
47
+
48
+ @property.setter
49
+ def property(self, value):
50
+
51
+ self._property = self.checkAndConvert(value, self._orderByType, "property")
52
+
53
+ @_builtInProperty
54
+ def sortDirection(self) -> SortDirection:
55
+ return self._sortDirection
56
+
57
+ @sortDirection.setter
58
+ def sortDirection(self, value: SortDirection):
59
+ self._sortDirection = self.checkAndConvert(
60
+ value, SortDirection, "sortDirection"
61
+ )
62
+
63
+ @_builtInProperty
64
+ def customFieldId(self) -> Optional[int]:
65
+ return self._customFieldId
66
+
67
+ @customFieldId.setter
68
+ def customFieldId(self, value: Optional[int]):
69
+ self._customFieldId = self.checkAndConvertNullable(value, int, "customFieldId")