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.
- LOGS/Auxiliary/CheckClassName.py +1075 -0
- LOGS/Auxiliary/Constants.py +99 -0
- LOGS/Auxiliary/CustomEntityClassGenerator.py +254 -0
- LOGS/Auxiliary/CustomFieldClassGenerator.py +115 -0
- LOGS/Auxiliary/CustomFieldValueTypeChecker.py +168 -0
- LOGS/Auxiliary/CustomSectionClassGenerator.py +113 -0
- LOGS/Auxiliary/CustomTypeClassGenerator.py +147 -0
- LOGS/Auxiliary/DateTimeConverter.py +66 -0
- LOGS/Auxiliary/Decorators.py +109 -0
- LOGS/Auxiliary/Exceptions.py +341 -0
- LOGS/Auxiliary/LOGSErrorResponse.py +89 -0
- LOGS/Auxiliary/MinimalModelGenerator.py +236 -0
- LOGS/Auxiliary/ParameterHelper.py +56 -0
- LOGS/Auxiliary/ReplaceMessage.py +13 -0
- LOGS/Auxiliary/Tools.py +432 -0
- LOGS/Auxiliary/__init__.py +15 -0
- LOGS/Converter/Conversion.py +248 -0
- LOGS/Converter/Converter.py +96 -0
- LOGS/Converter/ConverterParameter.py +88 -0
- LOGS/Converter/DateTimeRange.py +58 -0
- LOGS/Converter/ExportParameters.py +89 -0
- LOGS/Converter/__init__.py +13 -0
- LOGS/Entities/Attachment.py +84 -0
- LOGS/Entities/AttachmentMinimal.py +8 -0
- LOGS/Entities/AttachmentRequestParameter.py +42 -0
- LOGS/Entities/Attachments.py +53 -0
- LOGS/Entities/AutoloadFileInfo.py +12 -0
- LOGS/Entities/AutoloadStatusError.py +7 -0
- LOGS/Entities/AxisNaming.py +33 -0
- LOGS/Entities/AxisZoom.py +33 -0
- LOGS/Entities/Bridge.py +165 -0
- LOGS/Entities/BridgeClientInfo.py +93 -0
- LOGS/Entities/BridgeMinimal.py +8 -0
- LOGS/Entities/BridgeRequestParameter.py +49 -0
- LOGS/Entities/BridgeType.py +7 -0
- LOGS/Entities/Bridges.py +12 -0
- LOGS/Entities/CustomField.py +243 -0
- LOGS/Entities/CustomFieldMinimal.py +8 -0
- LOGS/Entities/CustomFieldModels.py +111 -0
- LOGS/Entities/CustomFieldRequestParameter.py +69 -0
- LOGS/Entities/CustomFieldSearchQuery.py +40 -0
- LOGS/Entities/CustomFields.py +12 -0
- LOGS/Entities/CustomType.py +212 -0
- LOGS/Entities/CustomTypeMinimal.py +8 -0
- LOGS/Entities/CustomTypeRequestParameter.py +60 -0
- LOGS/Entities/CustomTypeSection.py +63 -0
- LOGS/Entities/CustomTypes.py +12 -0
- LOGS/Entities/DataFormat.py +97 -0
- LOGS/Entities/DataFormatInstrument.py +18 -0
- LOGS/Entities/DataFormatInstrumentMinimal.py +8 -0
- LOGS/Entities/DataFormatInstrumentRequestParameter.py +17 -0
- LOGS/Entities/DataFormatInstruments.py +16 -0
- LOGS/Entities/DataFormatMinimal.py +18 -0
- LOGS/Entities/DataFormatRequestParameter.py +21 -0
- LOGS/Entities/DataFormats.py +12 -0
- LOGS/Entities/DataSource.py +218 -0
- LOGS/Entities/DataSourceConnectionStatus.py +12 -0
- LOGS/Entities/DataSourceMinimal.py +8 -0
- LOGS/Entities/DataSourceRequestParameter.py +57 -0
- LOGS/Entities/DataSourceStatus.py +108 -0
- LOGS/Entities/DataSourceStatusIterator.py +16 -0
- LOGS/Entities/DataSourceStatusRequestParameter.py +31 -0
- LOGS/Entities/DataSources.py +12 -0
- LOGS/Entities/Dataset.py +439 -0
- LOGS/Entities/DatasetBase.py +196 -0
- LOGS/Entities/DatasetCreator.py +148 -0
- LOGS/Entities/DatasetInfo.py +147 -0
- LOGS/Entities/DatasetMatchTypes.py +157 -0
- LOGS/Entities/DatasetMatching.py +196 -0
- LOGS/Entities/DatasetMinimal.py +8 -0
- LOGS/Entities/DatasetModels.py +33 -0
- LOGS/Entities/DatasetRequestParameter.py +92 -0
- LOGS/Entities/DatasetTemplate.py +23 -0
- LOGS/Entities/DatasetUploadParameter.py +14 -0
- LOGS/Entities/Datasets.py +142 -0
- LOGS/Entities/Datatrack.py +179 -0
- LOGS/Entities/DatatrackFormattedTable.py +25 -0
- LOGS/Entities/DatatrackGeneric.py +34 -0
- LOGS/Entities/DatatrackImage.py +25 -0
- LOGS/Entities/DatatrackNumericArray.py +30 -0
- LOGS/Entities/DatatrackNumericMatrix.py +98 -0
- LOGS/Entities/Entities.py +71 -0
- LOGS/Entities/EntitiesRequestParameter.py +18 -0
- LOGS/Entities/EntityOriginWriteModelWithId.py +15 -0
- LOGS/Entities/FileEntry.py +138 -0
- LOGS/Entities/FileExcludePattern.py +8 -0
- LOGS/Entities/FormatMetaData.py +56 -0
- LOGS/Entities/FormattedTable/DatatypeFormattedTable.py +135 -0
- LOGS/Entities/FormattedTable/DatatypeFormattedTableCell.py +108 -0
- LOGS/Entities/FormattedTable/DatatypeFormattedTableSettings.py +11 -0
- LOGS/Entities/FormattedTable/__init__.py +9 -0
- LOGS/Entities/HierarchyLeaf.py +15 -0
- LOGS/Entities/HierarchyNode.py +40 -0
- LOGS/Entities/ILiteraryTypedEntity.py +19 -0
- LOGS/Entities/InventoryItem.py +102 -0
- LOGS/Entities/InventoryItemMinimal.py +25 -0
- LOGS/Entities/InventoryItemRequestParameter.py +58 -0
- LOGS/Entities/InventoryItems.py +12 -0
- LOGS/Entities/LabNotebook.py +33 -0
- LOGS/Entities/LabNotebookEntries.py +16 -0
- LOGS/Entities/LabNotebookEntry.py +106 -0
- LOGS/Entities/LabNotebookEntryContent/BasicAttribute.py +15 -0
- LOGS/Entities/LabNotebookEntryContent/EntityAttribute.py +85 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentBlockquote.py +13 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentBulletList.py +17 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentCallout.py +40 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentContentPlaceholderNode.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentConverter.py +207 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentDocument.py +8 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentEntity.py +13 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentEntityMention.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentHeading.py +33 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentHorizontalRule.py +12 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentItem.py +37 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentListItem.py +49 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentOrderedList.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentParagraph.py +13 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTable.py +17 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTableCell.py +40 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTableRow.py +8 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTaskList.py +17 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTaskListItem.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentText.py +33 -0
- LOGS/Entities/LabNotebookEntryContent/IEntryContentWithAttribute.py +23 -0
- LOGS/Entities/LabNotebookEntryContent/IEntryContentWithContent.py +38 -0
- LOGS/Entities/LabNotebookEntryContent/IEntryContentWithTextAttribute.py +16 -0
- LOGS/Entities/LabNotebookEntryContent/TextAttribute.py +46 -0
- LOGS/Entities/LabNotebookEntryContent/TextMarkAtributes.py +64 -0
- LOGS/Entities/LabNotebookEntryContent/TextMarkConverter.py +45 -0
- LOGS/Entities/LabNotebookEntryContent/TextMarks.py +71 -0
- LOGS/Entities/LabNotebookEntryContent/__init__.py +34 -0
- LOGS/Entities/LabNotebookEntryMinimal.py +8 -0
- LOGS/Entities/LabNotebookEntryRequestParameter.py +59 -0
- LOGS/Entities/LabNotebookExperiment.py +58 -0
- LOGS/Entities/LabNotebookExperimentMinimal.py +8 -0
- LOGS/Entities/LabNotebookExperimentRequestParameter.py +52 -0
- LOGS/Entities/LabNotebookExperiments.py +16 -0
- LOGS/Entities/LabNotebookMinimal.py +8 -0
- LOGS/Entities/LabNotebookModels.py +14 -0
- LOGS/Entities/LabNotebookRequestParameter.py +42 -0
- LOGS/Entities/LabNotebookTemplate.py +42 -0
- LOGS/Entities/LabNotebookTemplateMinimal.py +8 -0
- LOGS/Entities/LabNotebookTemplateRequestParameter.py +38 -0
- LOGS/Entities/LabNotebookTemplates.py +16 -0
- LOGS/Entities/LabNotebooks.py +12 -0
- LOGS/Entities/Method.py +66 -0
- LOGS/Entities/MethodMinimal.py +8 -0
- LOGS/Entities/MethodRequestParameter.py +16 -0
- LOGS/Entities/Methods.py +12 -0
- LOGS/Entities/Origin.py +53 -0
- LOGS/Entities/OriginMinimal.py +8 -0
- LOGS/Entities/OriginRequestParameter.py +28 -0
- LOGS/Entities/Origins.py +12 -0
- LOGS/Entities/ParserLog.py +49 -0
- LOGS/Entities/Permission.py +9 -0
- LOGS/Entities/Person.py +145 -0
- LOGS/Entities/PersonCategory.py +12 -0
- LOGS/Entities/PersonMinimal.py +8 -0
- LOGS/Entities/PersonRequestParameter.py +58 -0
- LOGS/Entities/Persons.py +12 -0
- LOGS/Entities/Project.py +52 -0
- LOGS/Entities/ProjectMinimal.py +8 -0
- LOGS/Entities/ProjectPersonPermission.py +102 -0
- LOGS/Entities/ProjectRequestParameter.py +58 -0
- LOGS/Entities/Projects.py +12 -0
- LOGS/Entities/Role.py +94 -0
- LOGS/Entities/RoleMinimal.py +8 -0
- LOGS/Entities/RoleRequestParameter.py +40 -0
- LOGS/Entities/Roles.py +12 -0
- LOGS/Entities/RunState.py +9 -0
- LOGS/Entities/Sample.py +53 -0
- LOGS/Entities/SampleMinimal.py +8 -0
- LOGS/Entities/SampleRequestParameter.py +54 -0
- LOGS/Entities/Samples.py +12 -0
- LOGS/Entities/SharedContent.py +87 -0
- LOGS/Entities/SharedContentMinimal.py +8 -0
- LOGS/Entities/SharedContentRequestParameter.py +38 -0
- LOGS/Entities/SharedContents.py +12 -0
- LOGS/Entities/Signature.py +60 -0
- LOGS/Entities/Track.py +93 -0
- LOGS/Entities/TrackData.py +20 -0
- LOGS/Entities/TrackImage.py +21 -0
- LOGS/Entities/TrackImageData.py +20 -0
- LOGS/Entities/TrackMatrix.py +28 -0
- LOGS/Entities/TrackMatrixData.py +22 -0
- LOGS/Entities/TrackSettings.py +55 -0
- LOGS/Entities/TrackTable.py +21 -0
- LOGS/Entities/TrackTableData.py +22 -0
- LOGS/Entities/TrackXY.py +40 -0
- LOGS/Entities/TrackXYComplex.py +51 -0
- LOGS/Entities/TrackXYComplexData.py +50 -0
- LOGS/Entities/TrackXYData.py +31 -0
- LOGS/Entities/Vendor.py +40 -0
- LOGS/Entities/VendorMinimal.py +8 -0
- LOGS/Entities/VendorRequestParameter.py +17 -0
- LOGS/Entities/Vendors.py +12 -0
- LOGS/Entities/__init__.py +118 -0
- LOGS/Entity/ConnectedEntity.py +170 -0
- LOGS/Entity/Entity.py +203 -0
- LOGS/Entity/EntityConnector.py +70 -0
- LOGS/Entity/EntityIterator.py +263 -0
- LOGS/Entity/EntityMinimal.py +141 -0
- LOGS/Entity/EntityMinimalWithIntId.py +36 -0
- LOGS/Entity/EntityMinimalWithStrId.py +36 -0
- LOGS/Entity/EntityMinimalWithType.py +47 -0
- LOGS/Entity/EntityRequestParameter.py +104 -0
- LOGS/Entity/EntitySortBy.py +69 -0
- LOGS/Entity/EntityWithIntId.py +26 -0
- LOGS/Entity/EntityWithStrId.py +26 -0
- LOGS/Entity/IGenericEntityOrderBy.py +55 -0
- LOGS/Entity/IdIterator.py +207 -0
- LOGS/Entity/SerializableContent.py +834 -0
- LOGS/Entity/__init__.py +23 -0
- LOGS/Interfaces/ICustomFieldValue.py +92 -0
- LOGS/Interfaces/ICustomSectionValue.py +161 -0
- LOGS/Interfaces/ICustomTypeValue.py +152 -0
- LOGS/Interfaces/ICustomValue.py +28 -0
- LOGS/Interfaces/IEntityInterface.py +7 -0
- LOGS/Interfaces/IEntryRecord.py +57 -0
- LOGS/Interfaces/IHierarchicalEntity.py +41 -0
- LOGS/Interfaces/IHierarchyType.py +63 -0
- LOGS/Interfaces/ILockableEntity.py +52 -0
- LOGS/Interfaces/IModificationRecord.py +56 -0
- LOGS/Interfaces/INamedEntity.py +25 -0
- LOGS/Interfaces/IOwnedEntity.py +27 -0
- LOGS/Interfaces/IPaginationRequest.py +11 -0
- LOGS/Interfaces/IPermissionedEntity.py +72 -0
- LOGS/Interfaces/IProjectBased.py +27 -0
- LOGS/Interfaces/ISessionedEntity.py +59 -0
- LOGS/Interfaces/ISignableEntity.py +49 -0
- LOGS/Interfaces/ISoftDeletable.py +28 -0
- LOGS/Interfaces/ITypedEntity.py +129 -0
- LOGS/Interfaces/IUniqueEntity.py +61 -0
- LOGS/Interfaces/IVersionedEntity.py +39 -0
- LOGS/Interfaces/__init__.py +7 -0
- LOGS/LOGS.py +1436 -0
- LOGS/LOGSConnection.py +647 -0
- LOGS/LOGSOptions.py +11 -0
- LOGS/Parameters/Color.py +92 -0
- LOGS/Parameters/ParameterBase.py +55 -0
- LOGS/Parameters/ParameterConverter.py +24 -0
- LOGS/Parameters/ParameterElement.py +99 -0
- LOGS/Parameters/ParameterList.py +52 -0
- LOGS/Parameters/ParameterTable.py +64 -0
- LOGS/Parameters/__init__.py +13 -0
- LOGS/ServerMetaData.py +120 -0
- LOGS/__init__.py +12 -0
- logs_py-4.0.7.dist-info/METADATA +51 -0
- logs_py-4.0.7.dist-info/RECORD +251 -0
- logs_py-4.0.7.dist-info/WHEEL +5 -0
- logs_py-4.0.7.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import TYPE_CHECKING, Union
|
|
3
|
+
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from LOGS.Entities.Attachment import Attachment
|
|
6
|
+
from LOGS.Entities.Bridge import Bridge
|
|
7
|
+
from LOGS.Entities.CustomField import CustomField
|
|
8
|
+
from LOGS.Entities.CustomType import CustomType
|
|
9
|
+
from LOGS.Entities.DataFormat import DataFormat
|
|
10
|
+
from LOGS.Entities.DataFormatInstrument import DataFormatInstrument
|
|
11
|
+
from LOGS.Entities.Dataset import Dataset
|
|
12
|
+
from LOGS.Entities.DatasetTemplate import DatasetTemplate
|
|
13
|
+
from LOGS.Entities.DataSource import DataSource
|
|
14
|
+
from LOGS.Entities.FileEntry import FileEntry
|
|
15
|
+
from LOGS.Entities.InventoryItem import InventoryItem
|
|
16
|
+
from LOGS.Entities.LabNotebook import LabNotebook
|
|
17
|
+
from LOGS.Entities.LabNotebookEntry import LabNotebookEntry
|
|
18
|
+
from LOGS.Entities.LabNotebookExperiment import LabNotebookExperiment
|
|
19
|
+
from LOGS.Entities.LabNotebookTemplate import LabNotebookTemplate
|
|
20
|
+
from LOGS.Entities.Method import Method
|
|
21
|
+
from LOGS.Entities.Origin import Origin
|
|
22
|
+
from LOGS.Entities.Person import Person
|
|
23
|
+
from LOGS.Entities.Project import Project
|
|
24
|
+
from LOGS.Entities.Role import Role
|
|
25
|
+
from LOGS.Entities.Sample import Sample
|
|
26
|
+
from LOGS.Entities.Vendor import Vendor
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class Constants:
|
|
30
|
+
_control_character = {
|
|
31
|
+
"0": ("\u0000", "null"),
|
|
32
|
+
"1": ("\u0001", "start of heading"),
|
|
33
|
+
"2": ("\u0002", "start of text"),
|
|
34
|
+
"3": ("\u0003", "end of text"),
|
|
35
|
+
"4": ("\u0004", "end of transmission"),
|
|
36
|
+
"5": ("\u0005", "enquiry"),
|
|
37
|
+
"6": ("\u0006", "acknowledge"),
|
|
38
|
+
"7": ("\u0007", "bell"),
|
|
39
|
+
"8": ("\u0008", "backspace"),
|
|
40
|
+
"9": ("\u0009", "horizontal tabulation"),
|
|
41
|
+
"a": ("\u000a", "line feed"),
|
|
42
|
+
"b": ("\u000b", "vertical tabulation"),
|
|
43
|
+
"c": ("\u000c", "form feed"),
|
|
44
|
+
"d": ("\u000d", "carriage return"),
|
|
45
|
+
"e": ("\u000e", "shift out"),
|
|
46
|
+
"f": ("\u000f", "shift in"),
|
|
47
|
+
"10": ("\u0010", "data link escape"),
|
|
48
|
+
"11": ("\u0011", "device control one"),
|
|
49
|
+
"12": ("\u0012", "device control two"),
|
|
50
|
+
"13": ("\u0013", "device control three"),
|
|
51
|
+
"14": ("\u0014", "device control four"),
|
|
52
|
+
"15": ("\u0015", "negative acknowledge"),
|
|
53
|
+
"16": ("\u0016", "synchronous idle"),
|
|
54
|
+
"17": ("\u0017", "end of transmission block"),
|
|
55
|
+
"18": ("\u0018", "cancel"),
|
|
56
|
+
"19": ("\u0019", "end of medium"),
|
|
57
|
+
"1a": ("\u001a", "substitute"),
|
|
58
|
+
"1b": ("\u001b", "escape"),
|
|
59
|
+
"1c": ("\u001c", "file separator"),
|
|
60
|
+
"1d": ("\u001d", "group separator"),
|
|
61
|
+
"1e": ("\u001e", "record separator"),
|
|
62
|
+
"1f": ("\u001f", "unit separator"),
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
byteUnits = ["", "K", "M", "G", "T", "P", "E", "Z"]
|
|
66
|
+
|
|
67
|
+
exceptionIndentation = " " * 2
|
|
68
|
+
|
|
69
|
+
# Typing aliases constants
|
|
70
|
+
ID_TYPE = Union[int, str]
|
|
71
|
+
|
|
72
|
+
FILE_TYPE = Union[str, os.DirEntry, "FileEntry"]
|
|
73
|
+
|
|
74
|
+
TYPED_ENTITIES = Union[
|
|
75
|
+
"Sample", "Dataset", "InventoryItem", "DatasetTemplate", "Person", "Project"
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
ENTITIES = Union[
|
|
79
|
+
"Bridge",
|
|
80
|
+
"CustomField",
|
|
81
|
+
"CustomType",
|
|
82
|
+
"Dataset",
|
|
83
|
+
"DataSource",
|
|
84
|
+
"InventoryItem",
|
|
85
|
+
"LabNotebook",
|
|
86
|
+
"LabNotebookEntry",
|
|
87
|
+
"LabNotebookExperiment",
|
|
88
|
+
"LabNotebookTemplate",
|
|
89
|
+
"Origin",
|
|
90
|
+
"Person",
|
|
91
|
+
"Project",
|
|
92
|
+
"Sample",
|
|
93
|
+
"DataFormat",
|
|
94
|
+
"Role",
|
|
95
|
+
"Vendor",
|
|
96
|
+
"DataFormatInstrument",
|
|
97
|
+
"Method",
|
|
98
|
+
"Attachment",
|
|
99
|
+
]
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
from typing import (
|
|
3
|
+
TYPE_CHECKING,
|
|
4
|
+
Any,
|
|
5
|
+
Dict,
|
|
6
|
+
Generic,
|
|
7
|
+
Optional,
|
|
8
|
+
Type,
|
|
9
|
+
TypeVar,
|
|
10
|
+
Union,
|
|
11
|
+
cast,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
from LOGS.Auxiliary.CheckClassName import CheckClassName
|
|
15
|
+
from LOGS.Auxiliary.Constants import Constants
|
|
16
|
+
from LOGS.Auxiliary.Exceptions import TypedEntityNotConnectedException
|
|
17
|
+
from LOGS.Auxiliary.Tools import Tools
|
|
18
|
+
from LOGS.Entities.CustomFieldModels import CustomTypeEntityTypeMapper
|
|
19
|
+
from LOGS.Entity import Entity
|
|
20
|
+
from LOGS.Interfaces.ITypedEntity import ITypedEntity
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from LOGS.Entities.CustomType import CustomType
|
|
24
|
+
from LOGS.LOGSConnection import LOGSConnection
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
_T = TypeVar("_T", bound=Constants.TYPED_ENTITIES)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class CustomEntityClassGenerator(Generic[_T]):
|
|
31
|
+
|
|
32
|
+
_customTypeCache: Dict[str, "CustomType"] = {}
|
|
33
|
+
_classCache: Dict[str, Type[_T]] = {}
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def generate(
|
|
37
|
+
cls,
|
|
38
|
+
customType: Optional["CustomType"],
|
|
39
|
+
connection: "LOGSConnection",
|
|
40
|
+
fieldName: Optional[str] = None,
|
|
41
|
+
limitToEntityType: Optional[Type[_T]] = None,
|
|
42
|
+
) -> Type[_T]:
|
|
43
|
+
if customType is None:
|
|
44
|
+
if not limitToEntityType:
|
|
45
|
+
raise ValueError(
|
|
46
|
+
"When 'customType' is None, 'limitToEntityType' must be provided."
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
if not isinstance(limitToEntityType, type) or not issubclass(
|
|
50
|
+
limitToEntityType, Entity
|
|
51
|
+
):
|
|
52
|
+
raise ValueError("'limitToEntityType' must be an entity class.")
|
|
53
|
+
|
|
54
|
+
return limitToEntityType
|
|
55
|
+
else:
|
|
56
|
+
if not customType or not customType.id:
|
|
57
|
+
raise ValueError(f"Custom type is missing for field '{fieldName}'.")
|
|
58
|
+
|
|
59
|
+
cacheId = cls._getCacheKey(customType.id, connection)
|
|
60
|
+
if cacheId in cls._classCache:
|
|
61
|
+
return cls._classCache[cacheId]
|
|
62
|
+
|
|
63
|
+
if not customType.entityType:
|
|
64
|
+
raise ValueError(
|
|
65
|
+
f"Custom type '{customType.name}' (ID: {customType.id}) has no entity type defined."
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
entityType = CustomTypeEntityTypeMapper.getClass(customType.entityType)
|
|
69
|
+
|
|
70
|
+
if limitToEntityType and limitToEntityType != entityType:
|
|
71
|
+
raise Exception(
|
|
72
|
+
f"The custom type '{customType.name}' is not valid for entity type '{limitToEntityType.__name__}'. (Expected entity type '{entityType.__name__}')"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
name = (
|
|
76
|
+
entityType.__name__
|
|
77
|
+
+ "_"
|
|
78
|
+
+ (
|
|
79
|
+
CheckClassName.sanitizeClassName(customType.name)
|
|
80
|
+
if customType.name
|
|
81
|
+
else f"CustomType_ID{customType.id}"
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
doc = f"This class represents a LOGS {entityType.__name__} of custom type '{customType.name}' (TypeID: {customType.id})"
|
|
86
|
+
|
|
87
|
+
module = ".".join(
|
|
88
|
+
entityType.__module__.split(".")[:-1]
|
|
89
|
+
+ [f"Custom{Tools.wordToPlural(entityType.__name__)}"],
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
def __init__(
|
|
93
|
+
self,
|
|
94
|
+
ref=None,
|
|
95
|
+
id: Optional[int] = None,
|
|
96
|
+
connection: Optional["LOGSConnection"] = connection,
|
|
97
|
+
*args,
|
|
98
|
+
**kwargs,
|
|
99
|
+
):
|
|
100
|
+
cast(Any, type(self).__bases__[0]).__init__(
|
|
101
|
+
self,
|
|
102
|
+
ref=ref,
|
|
103
|
+
id=id,
|
|
104
|
+
connection=connection,
|
|
105
|
+
*args,
|
|
106
|
+
**kwargs,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
typeDict = {
|
|
110
|
+
"__init__": __init__,
|
|
111
|
+
"__module__": module,
|
|
112
|
+
"__doc__": doc,
|
|
113
|
+
"_customType": customType,
|
|
114
|
+
"_baseType": entityType,
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
newClass = cast(
|
|
118
|
+
Type[_T],
|
|
119
|
+
type(
|
|
120
|
+
name,
|
|
121
|
+
(entityType,),
|
|
122
|
+
typeDict,
|
|
123
|
+
),
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
return newClass
|
|
127
|
+
|
|
128
|
+
@classmethod
|
|
129
|
+
def _getCacheKey(
|
|
130
|
+
cls,
|
|
131
|
+
customTypeOrId: int,
|
|
132
|
+
connection: "LOGSConnection",
|
|
133
|
+
) -> str:
|
|
134
|
+
url = connection.getEndpointUrl(
|
|
135
|
+
["custom_type_entities"] + [str(customTypeOrId)],
|
|
136
|
+
)
|
|
137
|
+
return base64.b64encode(url.encode()).decode()
|
|
138
|
+
|
|
139
|
+
@classmethod
|
|
140
|
+
def fetchCustomType(
|
|
141
|
+
cls, customTypeOrId: Union["CustomType", int], connection: "LOGSConnection"
|
|
142
|
+
):
|
|
143
|
+
from LOGS.Entities.CustomType import CustomType
|
|
144
|
+
|
|
145
|
+
if isinstance(customTypeOrId, CustomType):
|
|
146
|
+
return customTypeOrId
|
|
147
|
+
|
|
148
|
+
if isinstance(customTypeOrId, int):
|
|
149
|
+
cacheId = cls._getCacheKey(customTypeOrId, connection)
|
|
150
|
+
if cacheId in cls._customTypeCache:
|
|
151
|
+
return cls._customTypeCache[cacheId]
|
|
152
|
+
|
|
153
|
+
customType = CustomType(id=customTypeOrId, connection=connection)
|
|
154
|
+
customType.fetch()
|
|
155
|
+
|
|
156
|
+
cls._customTypeCache[cacheId] = customType
|
|
157
|
+
return customType
|
|
158
|
+
|
|
159
|
+
raise ValueError(
|
|
160
|
+
f"Parameter '{customTypeOrId}' must be either a {CustomType.__name__} instance or an integer ID."
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
@classmethod
|
|
164
|
+
def convert(
|
|
165
|
+
cls,
|
|
166
|
+
value: Any,
|
|
167
|
+
customTypeOrId: Union["CustomType", int],
|
|
168
|
+
connection: "LOGSConnection",
|
|
169
|
+
fieldName: Optional[str] = None,
|
|
170
|
+
limitToEntityType: Optional[Type[_T]] = None,
|
|
171
|
+
) -> _T:
|
|
172
|
+
|
|
173
|
+
if isinstance(value, Entity):
|
|
174
|
+
return cast(_T, value)
|
|
175
|
+
|
|
176
|
+
customType = cls.fetchCustomType(customTypeOrId, connection)
|
|
177
|
+
|
|
178
|
+
c = cls.generate(customType, connection, fieldName, limitToEntityType)
|
|
179
|
+
try:
|
|
180
|
+
return c(value)
|
|
181
|
+
except Exception as e:
|
|
182
|
+
raise ValueError(
|
|
183
|
+
f"Field '{fieldName}' cannot be converted to '{c.__name__}': {str(e)}"
|
|
184
|
+
) from e
|
|
185
|
+
|
|
186
|
+
@classmethod
|
|
187
|
+
def convertToUntyped(cls, entity: _T, fieldName: Optional[str] = None) -> _T:
|
|
188
|
+
if not isinstance(entity, ITypedEntity) or not entity._baseType:
|
|
189
|
+
return entity
|
|
190
|
+
|
|
191
|
+
if not entity._connection:
|
|
192
|
+
raise TypedEntityNotConnectedException(entity)
|
|
193
|
+
|
|
194
|
+
customType = entity.customType
|
|
195
|
+
customValues = entity.customValues
|
|
196
|
+
|
|
197
|
+
entity._customType = None
|
|
198
|
+
entity._customValues = None
|
|
199
|
+
|
|
200
|
+
c = cls.generate(
|
|
201
|
+
None,
|
|
202
|
+
connection=entity._connection,
|
|
203
|
+
fieldName=fieldName,
|
|
204
|
+
limitToEntityType=cast(_T, entity._baseType),
|
|
205
|
+
)(entity, connection=entity._getConnection())
|
|
206
|
+
|
|
207
|
+
entity._customType = customType
|
|
208
|
+
entity._customValues = customValues
|
|
209
|
+
|
|
210
|
+
c._untypedCustomType = customType.toDict() if customType else None
|
|
211
|
+
c._untypedValues = cast(Any, customValues.toDict()) if customValues else None
|
|
212
|
+
return c
|
|
213
|
+
|
|
214
|
+
@classmethod
|
|
215
|
+
def convertFromUntyped(
|
|
216
|
+
cls,
|
|
217
|
+
entity: _T,
|
|
218
|
+
fieldName: Optional[str] = None,
|
|
219
|
+
limitToEntityType: Optional[Type[_T]] = None,
|
|
220
|
+
) -> _T:
|
|
221
|
+
if not isinstance(entity, ITypedEntity) or not entity._untypedCustomType:
|
|
222
|
+
return entity
|
|
223
|
+
|
|
224
|
+
if (
|
|
225
|
+
not isinstance(entity._untypedCustomType, dict)
|
|
226
|
+
or "id" not in entity._untypedCustomType
|
|
227
|
+
):
|
|
228
|
+
raise Exception(f"Custom type of {entity.identifier} is invalid.")
|
|
229
|
+
|
|
230
|
+
if not entity._connection:
|
|
231
|
+
raise TypedEntityNotConnectedException(entity)
|
|
232
|
+
|
|
233
|
+
customTypeId = entity._untypedCustomType["id"]
|
|
234
|
+
entity._untypedCustomType = None
|
|
235
|
+
values = entity._untypedValues
|
|
236
|
+
entity._untypedValues = None
|
|
237
|
+
|
|
238
|
+
customType = cls.fetchCustomType(customTypeId, entity._connection)
|
|
239
|
+
|
|
240
|
+
c = cls.generate(
|
|
241
|
+
customType,
|
|
242
|
+
connection=entity._connection,
|
|
243
|
+
fieldName=fieldName,
|
|
244
|
+
limitToEntityType=limitToEntityType,
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
try:
|
|
248
|
+
e = c(entity, connection=entity._getConnection())
|
|
249
|
+
except Exception as e:
|
|
250
|
+
raise ValueError(
|
|
251
|
+
f"Field '{fieldName}' cannot be converted to '{c.__name__}': {str(e)}"
|
|
252
|
+
) from e
|
|
253
|
+
e.customValues = values
|
|
254
|
+
return e
|
|
@@ -0,0 +1,115 @@
|
|
|
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.Constants import Constants
|
|
6
|
+
from LOGS.Auxiliary.Exceptions import EntityFetchingException
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from LOGS.Interfaces.ICustomFieldValue import ICustomFieldValue
|
|
10
|
+
from LOGS.LOGSConnection import LOGSConnection
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CustomFieldClassGenerator:
|
|
14
|
+
|
|
15
|
+
_classCache: Dict[str, Type["ICustomFieldValue"]] = {}
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def _getCacheKey(cls, customTypeField: int, connection: "LOGSConnection") -> str:
|
|
19
|
+
url = connection.getEndpointUrl(["custom_type_fields", customTypeField])
|
|
20
|
+
return b64encode(url.encode()).decode()
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def generate(
|
|
24
|
+
cls,
|
|
25
|
+
customFieldId: int,
|
|
26
|
+
connection: "LOGSConnection",
|
|
27
|
+
fieldName: Optional[str] = None,
|
|
28
|
+
) -> Type["ICustomFieldValue"]:
|
|
29
|
+
from LOGS.Entities.CustomField import CustomField
|
|
30
|
+
from LOGS.Interfaces.ICustomFieldValue import ICustomFieldValue
|
|
31
|
+
|
|
32
|
+
cacheId = cls._getCacheKey(customFieldId, connection)
|
|
33
|
+
if cacheId in cls._classCache:
|
|
34
|
+
return cls._classCache[cacheId]
|
|
35
|
+
|
|
36
|
+
customField = CustomField(id=customFieldId, connection=connection)
|
|
37
|
+
try:
|
|
38
|
+
customField.fetch()
|
|
39
|
+
except EntityFetchingException as e:
|
|
40
|
+
raise ValueError(
|
|
41
|
+
f"Custom field with ID {customFieldId} specified in '{fieldName}' not found:"
|
|
42
|
+
+ f"\n{Constants.exceptionIndentation}{str(e)}"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
if cacheId in cls._classCache:
|
|
46
|
+
return cls._classCache[cacheId]
|
|
47
|
+
|
|
48
|
+
name = (
|
|
49
|
+
CheckClassName.sanitizeClassName(customField.name)
|
|
50
|
+
if customField.name
|
|
51
|
+
else f"CustomField_ID{customField.id}"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
def __init__(self, ref=None):
|
|
55
|
+
cast(Any, type(self).__bases__[0]).__init__(self, ref, customField.dataType)
|
|
56
|
+
|
|
57
|
+
doc = (
|
|
58
|
+
f"This class represents the value of the LOGS custom field '{customField.name}' (ID: {customField.id})"
|
|
59
|
+
+ ("\n" + customField.description if customField.description else "")
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
module = ".".join(
|
|
63
|
+
ICustomFieldValue.__module__.split(".")[:-1]
|
|
64
|
+
+ ["GeneratedCustomFieldValues"],
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
newClass: Type[ICustomFieldValue] = type(
|
|
68
|
+
name,
|
|
69
|
+
(ICustomFieldValue,),
|
|
70
|
+
{
|
|
71
|
+
"__init__": __init__,
|
|
72
|
+
"_dataType": customField.dataType,
|
|
73
|
+
"__module__": module,
|
|
74
|
+
"__doc__": doc,
|
|
75
|
+
"_name": customField.name,
|
|
76
|
+
"_id": customField.id,
|
|
77
|
+
"_connection": connection,
|
|
78
|
+
"_value": (
|
|
79
|
+
customField.defaultValues
|
|
80
|
+
if customField.defaultValues is not None
|
|
81
|
+
else None
|
|
82
|
+
),
|
|
83
|
+
},
|
|
84
|
+
)
|
|
85
|
+
cls._classCache[cacheId] = newClass
|
|
86
|
+
|
|
87
|
+
return newClass
|
|
88
|
+
|
|
89
|
+
@classmethod
|
|
90
|
+
def convert(
|
|
91
|
+
cls,
|
|
92
|
+
value: Any,
|
|
93
|
+
customFieldId: int,
|
|
94
|
+
connection: "LOGSConnection",
|
|
95
|
+
fieldName: Optional[str] = None,
|
|
96
|
+
) -> Optional["ICustomFieldValue"]:
|
|
97
|
+
from LOGS.Interfaces.ICustomFieldValue import ICustomFieldValue
|
|
98
|
+
|
|
99
|
+
if isinstance(value, ICustomFieldValue):
|
|
100
|
+
return value
|
|
101
|
+
|
|
102
|
+
if not isinstance(value, dict):
|
|
103
|
+
raise ValueError(
|
|
104
|
+
f"Field '{fieldName}' cannot be converted from value of type '{type(value).__name__}'."
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
c = cls.generate(
|
|
108
|
+
customFieldId=customFieldId, fieldName=fieldName, connection=connection
|
|
109
|
+
)
|
|
110
|
+
try:
|
|
111
|
+
return c(value)
|
|
112
|
+
except Exception as e:
|
|
113
|
+
raise ValueError(
|
|
114
|
+
f"Field '{fieldName}' cannot be converted to '{c.__name__}': {str(e)}"
|
|
115
|
+
) from e
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
from datetime import date, datetime, time, timedelta
|
|
2
|
+
from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Union
|
|
3
|
+
|
|
4
|
+
from LOGS.Auxiliary.MinimalModelGenerator import MinimalModelGenerator
|
|
5
|
+
from LOGS.Auxiliary.Tools import Tools
|
|
6
|
+
from LOGS.Converter.DateTimeRange import DateTimeRange
|
|
7
|
+
from LOGS.Entities.CustomFieldModels import CustomFieldDataType
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from LOGS.LOGSConnection import LOGSConnection
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CustomFieldValueTypeChecker:
|
|
14
|
+
|
|
15
|
+
_customFieldTypeMap: Dict[CustomFieldDataType, Union[type, str, Callable]] = {
|
|
16
|
+
CustomFieldDataType.String: str,
|
|
17
|
+
CustomFieldDataType.StringArray: str,
|
|
18
|
+
CustomFieldDataType.Integer: int,
|
|
19
|
+
CustomFieldDataType.IntegerArray: int,
|
|
20
|
+
CustomFieldDataType.Float: float,
|
|
21
|
+
CustomFieldDataType.FloatArray: float,
|
|
22
|
+
CustomFieldDataType.Boolean: bool,
|
|
23
|
+
CustomFieldDataType.Date: date,
|
|
24
|
+
CustomFieldDataType.DateArray: date,
|
|
25
|
+
CustomFieldDataType.DateTime: datetime,
|
|
26
|
+
CustomFieldDataType.DateTimeArray: datetime,
|
|
27
|
+
CustomFieldDataType.Time: time,
|
|
28
|
+
CustomFieldDataType.TimeArray: time,
|
|
29
|
+
CustomFieldDataType.DateTimeRange: DateTimeRange,
|
|
30
|
+
CustomFieldDataType.TimeRange: lambda value: (
|
|
31
|
+
timedelta(seconds=value) if isinstance(value, (int, float)) else value
|
|
32
|
+
),
|
|
33
|
+
CustomFieldDataType.Dataset: "DatasetMinimal",
|
|
34
|
+
CustomFieldDataType.DatasetArray: "DatasetMinimal",
|
|
35
|
+
CustomFieldDataType.Sample: "SampleMinimal",
|
|
36
|
+
CustomFieldDataType.SampleArray: "SampleMinimal",
|
|
37
|
+
CustomFieldDataType.Project: "ProjectMinimal",
|
|
38
|
+
CustomFieldDataType.ProjectArray: "ProjectMinimal",
|
|
39
|
+
CustomFieldDataType.Person: "PersonMinimal",
|
|
40
|
+
CustomFieldDataType.PersonArray: "PersonMinimal",
|
|
41
|
+
CustomFieldDataType.Method: "MethodMinimal",
|
|
42
|
+
CustomFieldDataType.MethodArray: "MethodMinimal",
|
|
43
|
+
CustomFieldDataType.SharedContent: "SharedContentMinimal",
|
|
44
|
+
CustomFieldDataType.SharedContentArray: "SharedContentMinimal",
|
|
45
|
+
CustomFieldDataType.LabNotebook: "LabNotebookMinimal",
|
|
46
|
+
CustomFieldDataType.LabNotebookArray: "LabNotebookMinimal",
|
|
47
|
+
CustomFieldDataType.LabNotebookExperiment: "LabNotebookExperimentMinimal",
|
|
48
|
+
CustomFieldDataType.LabNotebookExperimentArray: "LabNotebookExperimentMinimal",
|
|
49
|
+
CustomFieldDataType.LabNotebookEntry: "LabNotebookEntryMinimal",
|
|
50
|
+
CustomFieldDataType.LabNotebookEntryArray: "LabNotebookEntryMinimal",
|
|
51
|
+
CustomFieldDataType.Attachment: "AttachmentMinimal",
|
|
52
|
+
CustomFieldDataType.InventoryItem: "InventoryItemMinimal",
|
|
53
|
+
CustomFieldDataType.InventoryItemArray: "InventoryItemMinimal",
|
|
54
|
+
CustomFieldDataType.Barcode: str,
|
|
55
|
+
CustomFieldDataType.Url: str,
|
|
56
|
+
CustomFieldDataType.UrlArray: str,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
_converter: Callable[[Any, str], Any]
|
|
60
|
+
_isArrayType: bool
|
|
61
|
+
_enumOptions: Any = None
|
|
62
|
+
|
|
63
|
+
@classmethod
|
|
64
|
+
def _arrayTypeCheck(cls, data_type: CustomFieldDataType) -> bool:
|
|
65
|
+
return data_type.name.endswith("Array")
|
|
66
|
+
|
|
67
|
+
@classmethod
|
|
68
|
+
def _generateConverter(
|
|
69
|
+
cls,
|
|
70
|
+
dataType: CustomFieldDataType,
|
|
71
|
+
isArrayType: bool,
|
|
72
|
+
connection: Optional["LOGSConnection"],
|
|
73
|
+
) -> Callable[[Any, str], Any]:
|
|
74
|
+
dataClass = cls._customFieldTypeMap.get(dataType, None)
|
|
75
|
+
|
|
76
|
+
if dataClass is None:
|
|
77
|
+
raise ValueError(f"Unknown custom field type: '{dataType}'")
|
|
78
|
+
|
|
79
|
+
if isinstance(dataClass, str):
|
|
80
|
+
if isArrayType:
|
|
81
|
+
return lambda value, fieldName: MinimalModelGenerator.MinimalFromList(
|
|
82
|
+
value, dataClass, fieldName, connection
|
|
83
|
+
)
|
|
84
|
+
else:
|
|
85
|
+
return lambda value, fieldName: MinimalModelGenerator.MinimalFromSingle(
|
|
86
|
+
value, dataClass, fieldName, connection
|
|
87
|
+
)
|
|
88
|
+
elif isinstance(dataClass, type):
|
|
89
|
+
if isArrayType:
|
|
90
|
+
return lambda value, fieldName: Tools.checkListAndConvert(
|
|
91
|
+
value, dataClass, fieldName, allowNone=True
|
|
92
|
+
)
|
|
93
|
+
else:
|
|
94
|
+
return lambda value, fieldName: Tools.checkAndConvert(
|
|
95
|
+
value, dataClass, f"{fieldName} <{dataType.name}>", allowNone=True
|
|
96
|
+
)
|
|
97
|
+
elif callable(dataClass):
|
|
98
|
+
if isArrayType:
|
|
99
|
+
return lambda value, fieldName: Tools.checkListAndConvert(
|
|
100
|
+
value, dataType.name, fieldName, dataClass, allowNone=True
|
|
101
|
+
)
|
|
102
|
+
else:
|
|
103
|
+
return lambda value, fieldName: Tools.checkAndConvert(
|
|
104
|
+
value, dataType.name, fieldName, dataClass, allowNone=True
|
|
105
|
+
)
|
|
106
|
+
else:
|
|
107
|
+
raise ValueError(f"Cannot create converter for type '{dataType}'")
|
|
108
|
+
|
|
109
|
+
def __str__(self):
|
|
110
|
+
s = " array" if self._isArrayType else ""
|
|
111
|
+
return f"<{type(self).__name__} [{self.dataType.name}]{s}>"
|
|
112
|
+
|
|
113
|
+
def __init__(
|
|
114
|
+
self,
|
|
115
|
+
dataType: CustomFieldDataType,
|
|
116
|
+
connection: Optional["LOGSConnection"],
|
|
117
|
+
enumOptions: Any = None,
|
|
118
|
+
):
|
|
119
|
+
Tools.checkAndConvert(
|
|
120
|
+
dataType, CustomFieldDataType, "dataType", allowNone=False
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
self.dataType = dataType
|
|
124
|
+
self._isArrayType = self._arrayTypeCheck(dataType)
|
|
125
|
+
self._converter = self._generateConverter(
|
|
126
|
+
dataType, self._isArrayType, connection
|
|
127
|
+
)
|
|
128
|
+
self.enumOptions = enumOptions
|
|
129
|
+
|
|
130
|
+
def checkAndConvertIgnoreEnumOptions(self, value: Any, fieldName: str = "value"):
|
|
131
|
+
if not self._isArrayType and isinstance(value, list):
|
|
132
|
+
return [
|
|
133
|
+
self._converter(v, f"{fieldName}[{i}]") for i, v in enumerate(value)
|
|
134
|
+
]
|
|
135
|
+
return self._converter(value, fieldName)
|
|
136
|
+
|
|
137
|
+
def checkAndConvert(self, value: Any, fieldName: str = "value", allowNone=True):
|
|
138
|
+
if allowNone and value is None:
|
|
139
|
+
return None
|
|
140
|
+
result = self._converter(value, fieldName)
|
|
141
|
+
if self._isArrayType:
|
|
142
|
+
if self._enumOptions:
|
|
143
|
+
for i, v in enumerate(result):
|
|
144
|
+
if v not in self._enumOptions:
|
|
145
|
+
raise ValueError(
|
|
146
|
+
f"Value of field '{fieldName}[{i}]' must be out of enumOptions. (Value '{Tools.truncString(str(v))}' is not accepted)"
|
|
147
|
+
)
|
|
148
|
+
else:
|
|
149
|
+
if self._enumOptions and result not in self._enumOptions:
|
|
150
|
+
raise ValueError(
|
|
151
|
+
f"Value of field '{fieldName}' must be out of enumOptions. (Value '{Tools.truncString(str(result))}' is not accepted)"
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
return result
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def enumOptions(self) -> Any:
|
|
158
|
+
return self._enumOptions
|
|
159
|
+
|
|
160
|
+
@enumOptions.setter
|
|
161
|
+
def enumOptions(self, value: Any):
|
|
162
|
+
if not value:
|
|
163
|
+
self._enumOptions = None
|
|
164
|
+
return
|
|
165
|
+
|
|
166
|
+
self._enumOptions = Tools.checkAndConvert(
|
|
167
|
+
value, list, "enumOptions", allowNone=False
|
|
168
|
+
)
|