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,113 @@
1
+ from base64 import b64encode
2
+ from typing import TYPE_CHECKING, Any, Dict, Optional, Type, cast
3
+
4
+ from LOGS.Auxiliary.CheckClassName import CheckClassName
5
+ from LOGS.Auxiliary.CustomFieldClassGenerator import CustomFieldClassGenerator
6
+ from LOGS.Auxiliary.Tools import Tools
7
+ from LOGS.Interfaces.ICustomSectionValue import ICustomSectionValue
8
+
9
+ if TYPE_CHECKING:
10
+ from LOGS.Entities.CustomTypeSection import CustomTypeSection
11
+ from LOGS.LOGSConnection import LOGSConnection
12
+
13
+
14
+ class CustomSectionClassGenerator:
15
+
16
+ _classCache: Dict[str, Type["ICustomSectionValue"]] = {}
17
+
18
+ @classmethod
19
+ def _getCacheKey(cls, customTypeSection: str, connection: "LOGSConnection") -> str:
20
+ url = connection.getEndpointUrl(["custom_type_sections", customTypeSection])
21
+ return b64encode(url.encode()).decode()
22
+
23
+ @classmethod
24
+ def generate(
25
+ cls,
26
+ section: "CustomTypeSection",
27
+ customTypeId: int,
28
+ sectionIndex: int,
29
+ connection: "LOGSConnection",
30
+ fieldName: Optional[str] = None,
31
+ ) -> Type["ICustomSectionValue"]:
32
+
33
+ if not customTypeId >= 0:
34
+ raise ValueError(
35
+ f"Section customTypeId is missing for section in field '{fieldName}'."
36
+ )
37
+
38
+ if not sectionIndex >= 0:
39
+ raise ValueError(
40
+ f"Section index is missing for section {sectionIndex} in field '{fieldName}'."
41
+ )
42
+
43
+ id = ICustomSectionValue._generateId(customTypeId, sectionIndex)
44
+ cacheId = cls._getCacheKey(id, connection)
45
+ if cacheId in cls._classCache:
46
+ return cls._classCache[cacheId]
47
+
48
+ customFields = (
49
+ [
50
+ CustomFieldClassGenerator.generate(
51
+ customFieldId=c.id, fieldName=fieldName, connection=connection
52
+ )
53
+ for c in section.customFields
54
+ if c and c.id
55
+ ]
56
+ if section.customFields
57
+ else []
58
+ )
59
+
60
+ name = (
61
+ CheckClassName.sanitizeClassName(section.name)
62
+ if section.name
63
+ else f"Section_TypeID{customTypeId}_Index{sectionIndex}"
64
+ )
65
+
66
+ module = ".".join(
67
+ ICustomSectionValue.__module__.split(".")[:-1]
68
+ + ["GeneratedCustomSectionValues"],
69
+ )
70
+
71
+ class CustomFieldProperty:
72
+ def __init__(self, name: str):
73
+ self.name = name
74
+
75
+ def __get__(self, instance: ICustomSectionValue, _):
76
+ return instance.getField(self.name)
77
+
78
+ def __set__(self, instance: ICustomSectionValue, value):
79
+ instance.setField(self.name, value)
80
+
81
+ def __init__(self, ref=None):
82
+ cast(Any, type(self).__bases__[0]).__init__(self, ref)
83
+
84
+ typeDict = {
85
+ "__init__": __init__,
86
+ "__module__": module,
87
+ "__doc__": f"This class represents the value of the LOGS custom field '{section.name}' (TypeID: {customTypeId} Index: {sectionIndex} )",
88
+ "_name": section.name,
89
+ "_customTypeId": customTypeId,
90
+ "_sectionIndex": sectionIndex,
91
+ "_fieldNames": [],
92
+ "_fieldTypes": {},
93
+ "_fieldIds": {},
94
+ "_noSerialize": ["fieldNames"],
95
+ }
96
+
97
+ for f in customFields:
98
+ attrName = Tools.resolveKeyConflictWithPrefix(f.__name__, "_", typeDict)
99
+
100
+ typeDict["_" + attrName] = None
101
+ typeDict[attrName] = CustomFieldProperty(attrName)
102
+ typeDict["_fieldNames"].append(attrName)
103
+ typeDict["_fieldTypes"][attrName] = f
104
+ typeDict["_fieldIds"][f._id] = attrName
105
+
106
+ typeDict["_noSerialize"] += typeDict["_fieldNames"]
107
+
108
+ newClass: Type[ICustomSectionValue] = type(
109
+ name,
110
+ (ICustomSectionValue,),
111
+ typeDict,
112
+ )
113
+ return newClass
@@ -0,0 +1,147 @@
1
+ from base64 import b64encode
2
+ from typing import TYPE_CHECKING, Any, Dict, Optional, Type, TypeVar, Union, cast
3
+
4
+ from LOGS.Auxiliary.CheckClassName import CheckClassName
5
+ from LOGS.Auxiliary.Constants import Constants
6
+ from LOGS.Auxiliary.CustomSectionClassGenerator import CustomSectionClassGenerator
7
+ from LOGS.Auxiliary.Exceptions import EntityFetchingException
8
+ from LOGS.Auxiliary.Tools import Tools
9
+ from LOGS.Interfaces.ICustomSectionValue import ICustomSectionValue
10
+ from LOGS.Interfaces.ICustomTypeValue import ICustomTypeValue
11
+
12
+ if TYPE_CHECKING:
13
+ from LOGS.Entities.CustomType import CustomType
14
+ from LOGS.LOGSConnection import LOGSConnection
15
+
16
+
17
+ _T = TypeVar("_T")
18
+
19
+
20
+ class CustomTypeClassGenerator:
21
+
22
+ _classCache: Dict[str, Type["ICustomTypeValue"]] = {}
23
+
24
+ @classmethod
25
+ def _getCacheKey(cls, customTypeOrId: int, connection: "LOGSConnection") -> str:
26
+ url = connection.getEndpointUrl(
27
+ ["custom_types", str(customTypeOrId)],
28
+ )
29
+ return b64encode(url.encode()).decode()
30
+
31
+ @classmethod
32
+ def generate(
33
+ cls,
34
+ customType: "CustomType",
35
+ connection: "LOGSConnection",
36
+ fieldName: Optional[str] = None,
37
+ ):
38
+
39
+ if not customType or not customType.id:
40
+ raise ValueError(f"Custom type is missing for field '{fieldName}'.")
41
+
42
+ cacheId = cls._getCacheKey(customType.id, connection)
43
+ if cacheId in cls._classCache:
44
+ return cls._classCache[cacheId]
45
+
46
+ sections = (
47
+ [
48
+ CustomSectionClassGenerator.generate(
49
+ section,
50
+ customTypeId=customType.id,
51
+ sectionIndex=i,
52
+ connection=connection,
53
+ )
54
+ for i, section in enumerate(customType.sections)
55
+ ]
56
+ if customType.sections
57
+ else []
58
+ )
59
+
60
+ name = (
61
+ CheckClassName.sanitizeClassName(customType.name)
62
+ if customType.name
63
+ else f"CustomType_ID{customType.id}"
64
+ )
65
+
66
+ module = ".".join(
67
+ ICustomTypeValue.__module__.split(".")[:-1] + ["GeneratedCustomTypeValues"],
68
+ )
69
+
70
+ class SectionProperty:
71
+ def __init__(self, name: str):
72
+ self.name = name
73
+
74
+ def __get__(self, instance: ICustomSectionValue, _):
75
+ return instance.getField(self.name)
76
+
77
+ def __init__(self, ref=None):
78
+ cast(Any, type(self).__bases__[0]).__init__(self, ref)
79
+
80
+ typeDict = {
81
+ "__init__": __init__,
82
+ "__module__": module,
83
+ "__doc__": f"This class represents the value of the LOGS custom type '{customType.name}' (TypeID: {customType.id})",
84
+ "_name": customType.name,
85
+ "_id": customType.id,
86
+ "_fieldNames": [],
87
+ "_fieldTypes": {},
88
+ "_fieldIds": {},
89
+ "_noSerialize": ["fieldNames"],
90
+ }
91
+
92
+ for s in sections:
93
+ attrName = Tools.resolveKeyConflictWithPrefix(s.__name__, "_", typeDict)
94
+
95
+ typeDict["_" + attrName] = None
96
+ typeDict[attrName] = SectionProperty(attrName)
97
+ typeDict["_fieldNames"].append(attrName)
98
+ typeDict["_fieldTypes"][attrName] = s
99
+ typeDict["_fieldIds"][s.getId()] = attrName
100
+
101
+ typeDict["_noSerialize"] += typeDict["_fieldNames"]
102
+
103
+ newClass: Type[ICustomTypeValue] = type(
104
+ name,
105
+ (ICustomTypeValue,),
106
+ typeDict,
107
+ )
108
+
109
+ return newClass
110
+
111
+ @classmethod
112
+ def convert(
113
+ cls,
114
+ value: Any,
115
+ customTypeOrId: Union["CustomType", int],
116
+ connection: "LOGSConnection",
117
+ fieldName: Optional[str] = None,
118
+ ) -> Optional["ICustomTypeValue"]:
119
+ from LOGS.Entities.CustomType import CustomType
120
+
121
+ if isinstance(value, ICustomTypeValue):
122
+ return value
123
+
124
+ if not isinstance(value, list):
125
+ raise ValueError(
126
+ f"Field '{fieldName}' cannot be converted from value of type '{type(value).__name__}'."
127
+ )
128
+
129
+ if isinstance(customTypeOrId, int):
130
+ customType = CustomType(id=customTypeOrId, connection=connection)
131
+ try:
132
+ customType.fetch()
133
+ except EntityFetchingException as e:
134
+ raise ValueError(
135
+ f"Field '{fieldName}' cannot be converted:"
136
+ + f"\n{Constants.exceptionIndentation}{str(e)}"
137
+ )
138
+ else:
139
+ customType = customTypeOrId
140
+
141
+ c = cls.generate(customType, connection, fieldName)
142
+ try:
143
+ return c(value)
144
+ except Exception as e:
145
+ raise ValueError(
146
+ f"Field '{fieldName}' cannot be converted to '{c.__name__}': {str(e)}"
147
+ ) from e
@@ -0,0 +1,66 @@
1
+ import datetime as dt
2
+ import re
3
+ import time
4
+ from typing import List, cast
5
+
6
+ import pytz
7
+
8
+
9
+ class DateTimeConverter:
10
+ # When adding pattern here put the pattern with most information on top
11
+ _datePatterns = ["%Y-%m-%dT%H:%M:%S.%fZ", "%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%d"]
12
+ _timePatterns = ["%H:%M:%S.%f", "%H:%M:%S", "%H:%M"]
13
+ utc_offset_re = re.compile(r"([\+-])(\d+)$")
14
+ multiSpace_re = re.compile(r"( {2,})")
15
+
16
+ @classmethod
17
+ def _getLocalTime(cls):
18
+ import platform
19
+
20
+ if platform.system() == "Windows":
21
+ from tzlocal.win32 import get_localzone_name
22
+
23
+ return pytz.timezone(get_localzone_name())
24
+ else:
25
+ return pytz.timezone(time.tzname[0])
26
+
27
+ @classmethod
28
+ def convertTime(cls, entry: str):
29
+ entry = re.sub(cls.multiSpace_re, " ", entry)
30
+ match = cls.utc_offset_re.search(entry)
31
+ if match and len(match.group(2)) == 3:
32
+ entry = entry.replace(match.group(0), match.group(1) + "0" + match.group(2))
33
+
34
+ times: List[dt.time] = []
35
+ for pattern in set(cast(List[str], cls._timePatterns)):
36
+ try:
37
+ times.append(dt.datetime.strptime(entry, pattern).time())
38
+ except:
39
+ continue
40
+ if len(times) < 1:
41
+ return None
42
+
43
+ return times[0]
44
+
45
+ @classmethod
46
+ def convertDateTime(cls, entry: str):
47
+ entry = re.sub(cls.multiSpace_re, " ", entry)
48
+ match = cls.utc_offset_re.search(entry)
49
+ if match and len(match.group(2)) == 3:
50
+ entry = entry.replace(match.group(0), match.group(1) + "0" + match.group(2))
51
+
52
+ dates: List[dt.datetime] = []
53
+ for pattern in set(cast(List[str], cls._datePatterns)):
54
+ try:
55
+ dates.append(dt.datetime.strptime(entry, pattern))
56
+ except:
57
+ continue
58
+ if len(dates) < 1:
59
+ return None
60
+
61
+ d = dates[0]
62
+ if d.tzinfo == pytz.UTC or d.tzinfo is None:
63
+ local_tz = cls._getLocalTime()
64
+ d = d.replace(tzinfo=pytz.utc).astimezone(local_tz)
65
+
66
+ return d
@@ -0,0 +1,109 @@
1
+ import types
2
+ from typing import Any, Callable, List, Type, TypeVar, Union, cast
3
+
4
+ TClass = TypeVar("TClass", bound=Callable[..., Any])
5
+
6
+
7
+ class InitConstructor:
8
+ def _set_new_attribute(self, name, value):
9
+ # Never overwrites an existing attribute. Returns True if the
10
+ # attribute already exists.
11
+ if name in self.__dict__:
12
+ return True
13
+ setattr(self, name, value)
14
+ return False
15
+
16
+ def _new_constructor(self):
17
+ print("New Constructor")
18
+
19
+ def __call__(self, classInput: TClass) -> TClass:
20
+ print(classInput.__class__)
21
+ c = cast(Type, classInput)
22
+
23
+ print(c.__init__.__code__.co_varnames)
24
+ print(c.__init__.__defaults__)
25
+ print(c.__init__.__code__)
26
+
27
+ constructor = types.FunctionType(self._new_constructor.__code__, {})
28
+
29
+ return classInput
30
+
31
+
32
+ class Endpoint:
33
+ def __init__(self, path: Union[List[str], str]) -> None:
34
+ self.path = [path] if isinstance(path, str) else path
35
+
36
+ def __call__(self, classInput: TClass) -> TClass:
37
+ from LOGS.Entity.ConnectedEntity import ConnectedEntity
38
+ from LOGS.Entity.EntityConnector import EntityConnector
39
+
40
+ if not isinstance(classInput, type) or not issubclass(
41
+ classInput, (ConnectedEntity, EntityConnector)
42
+ ):
43
+ raise Exception(
44
+ "%s decorator expect %a or %a type. (got type %a)"
45
+ % (
46
+ Endpoint.__name__,
47
+ ConnectedEntity.__name__,
48
+ EntityConnector.__name__,
49
+ classInput.__name__,
50
+ )
51
+ )
52
+
53
+ classInput._endpoint = self.path
54
+
55
+ return cast(TClass, classInput)
56
+
57
+
58
+ class UiEndpoint:
59
+ def __init__(self, path: Union[List[str], str]) -> None:
60
+ self.path = [path] if isinstance(path, str) else path
61
+
62
+ def __call__(self, classInput: TClass) -> TClass:
63
+ from LOGS.Entity.ConnectedEntity import ConnectedEntity
64
+
65
+ if not isinstance(classInput, type) or not issubclass(
66
+ classInput, (ConnectedEntity)
67
+ ):
68
+ raise Exception(
69
+ "%s decorator expect %a type. (got type %a)"
70
+ % (Endpoint.__name__, ConnectedEntity.__name__, classInput.__name__)
71
+ )
72
+
73
+ classInput._uiEndpoint = self.path
74
+
75
+ return cast(TClass, classInput)
76
+
77
+
78
+ class FullModel:
79
+ def __init__(self, fullEntity: Any) -> None:
80
+ self.fullEntity = fullEntity
81
+
82
+ def __call__(self, classInput: TClass) -> TClass:
83
+ if hasattr(classInput, "_fullEntityType"):
84
+ setattr(classInput, "_fullEntityType", self.fullEntity)
85
+ if hasattr(self.fullEntity, "_endpoint") and hasattr(classInput, "_endpoint"):
86
+ setattr(classInput, "_endpoint", getattr(self.fullEntity, "_endpoint"))
87
+
88
+ return classInput
89
+
90
+
91
+ # --- Example for typed function decorator ---
92
+ # TFun = TypeVar("TFun", bound=Callable[..., Any])
93
+
94
+ # class FunctionDecorator:
95
+ # def __init__(self, path: Union[List[str], str]) -> None:
96
+ # self.path = [path] if isinstance(path, str) else path
97
+
98
+ # def __call__(self, func: TFun) -> TFun:
99
+ # path = self.path
100
+
101
+ # @wraps(func)
102
+ # def wrapper(*args, **kwargs) -> Any:
103
+ # # if isclass(classInput) and issubclass(classInput, ConnectedContent):
104
+ # # cast(ConnectedContent, classInput)._endpoint = path
105
+ # if hasattr(func, "_endpoint"):
106
+ # setattr(func, "_endpoint", path)
107
+ # return func(*args, **kwargs)
108
+
109
+ # return cast(TFun, wrapper)