benchling-sdk 1.9.0a4__py3-none-any.whl → 1.10.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- benchling_sdk/apps/canvas/__init__.py +0 -0
- benchling_sdk/apps/canvas/errors.py +14 -0
- benchling_sdk/apps/{helpers/canvas_helpers.py → canvas/framework.py} +129 -188
- benchling_sdk/apps/canvas/types.py +125 -0
- benchling_sdk/apps/config/__init__.py +0 -3
- benchling_sdk/apps/config/decryption_provider.py +1 -1
- benchling_sdk/apps/config/errors.py +38 -0
- benchling_sdk/apps/config/framework.py +343 -0
- benchling_sdk/apps/config/helpers.py +157 -0
- benchling_sdk/apps/config/{mock_dependencies.py → mock_config.py} +78 -99
- benchling_sdk/apps/config/types.py +36 -0
- benchling_sdk/apps/framework.py +49 -338
- benchling_sdk/apps/helpers/webhook_helpers.py +2 -2
- benchling_sdk/apps/status/__init__.py +0 -0
- benchling_sdk/apps/status/errors.py +85 -0
- benchling_sdk/apps/{helpers/session_helpers.py → status/framework.py} +58 -167
- benchling_sdk/apps/status/helpers.py +20 -0
- benchling_sdk/apps/status/types.py +45 -0
- benchling_sdk/apps/types.py +3 -0
- benchling_sdk/errors.py +4 -4
- benchling_sdk/helpers/retry_helpers.py +3 -1
- benchling_sdk/models/__init__.py +44 -0
- benchling_sdk/services/v2/beta/{v2_beta_dataset_service.py → v2_beta_data_frame_service.py} +126 -116
- benchling_sdk/services/v2/stable/assay_result_service.py +18 -0
- benchling_sdk/services/v2/v2_beta_service.py +11 -11
- {benchling_sdk-1.9.0a4.dist-info → benchling_sdk-1.10.0.dist-info}/METADATA +4 -4
- {benchling_sdk-1.9.0a4.dist-info → benchling_sdk-1.10.0.dist-info}/RECORD +30 -21
- benchling_sdk/apps/config/dependencies.py +0 -1085
- benchling_sdk/apps/config/scalars.py +0 -226
- benchling_sdk/apps/helpers/config_helpers.py +0 -409
- /benchling_sdk/apps/{helpers → config}/cryptography_helpers.py +0 -0
- {benchling_sdk-1.9.0a4.dist-info → benchling_sdk-1.10.0.dist-info}/LICENSE +0 -0
- {benchling_sdk-1.9.0a4.dist-info → benchling_sdk-1.10.0.dist-info}/WHEEL +0 -0
@@ -1,226 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from abc import ABC, abstractmethod
|
4
|
-
from datetime import date, datetime
|
5
|
-
import json
|
6
|
-
from typing import Any, Dict, Generic, List, Optional, TypeVar, Union
|
7
|
-
|
8
|
-
from benchling_sdk.models import (
|
9
|
-
BooleanAppConfigItemType,
|
10
|
-
DateAppConfigItemType,
|
11
|
-
DatetimeAppConfigItemType,
|
12
|
-
FieldType,
|
13
|
-
FloatAppConfigItemType,
|
14
|
-
IntegerAppConfigItemType,
|
15
|
-
JsonAppConfigItemType,
|
16
|
-
SecureTextAppConfigItemType,
|
17
|
-
TextAppConfigItemType,
|
18
|
-
)
|
19
|
-
|
20
|
-
JsonType = Union[Dict[str, Any], List[Any], str, int, float, bool]
|
21
|
-
ScalarType = TypeVar("ScalarType", bool, date, datetime, float, int, JsonType, str)
|
22
|
-
# JsonType support requires object to be unioned. Currently we do it inline.
|
23
|
-
ScalarModelType = Union[bool, date, datetime, float, int, str]
|
24
|
-
# Enum values cannot be used in literals, so copy the strings
|
25
|
-
ScalarConfigItemType = Union[
|
26
|
-
BooleanAppConfigItemType,
|
27
|
-
DateAppConfigItemType,
|
28
|
-
DatetimeAppConfigItemType,
|
29
|
-
FloatAppConfigItemType,
|
30
|
-
IntegerAppConfigItemType,
|
31
|
-
JsonAppConfigItemType,
|
32
|
-
SecureTextAppConfigItemType,
|
33
|
-
TextAppConfigItemType,
|
34
|
-
]
|
35
|
-
|
36
|
-
|
37
|
-
class ScalarDefinition(ABC, Generic[ScalarType]):
|
38
|
-
"""
|
39
|
-
Scalar definition.
|
40
|
-
|
41
|
-
Map how ScalarConfigTypes values can be converted into corresponding Python types.
|
42
|
-
"""
|
43
|
-
|
44
|
-
@classmethod
|
45
|
-
def init(cls):
|
46
|
-
"""Init."""
|
47
|
-
return cls()
|
48
|
-
|
49
|
-
@classmethod
|
50
|
-
@abstractmethod
|
51
|
-
def from_str(cls, value: Optional[str]) -> Optional[ScalarType]:
|
52
|
-
"""
|
53
|
-
From string.
|
54
|
-
|
55
|
-
Given an optional string value of scalar configuration, produce an Optional instance of the
|
56
|
-
specific ScalarType. For instance, converting str to int.
|
57
|
-
|
58
|
-
Used when coercing Python types from string values in API responses.
|
59
|
-
"""
|
60
|
-
pass
|
61
|
-
|
62
|
-
|
63
|
-
class BoolScalar(ScalarDefinition[bool]):
|
64
|
-
"""
|
65
|
-
Bool Scalar.
|
66
|
-
|
67
|
-
Turn a Boolean-like string value into bool. Any permutation of "true" - case insensitive - is interpreted
|
68
|
-
as True. Any other non-empty string is False.
|
69
|
-
"""
|
70
|
-
|
71
|
-
@classmethod
|
72
|
-
def from_str(cls, value: Optional[str]) -> Optional[bool]:
|
73
|
-
"""Convert optional str to optional bool."""
|
74
|
-
# Though the spec declares str, this is actually being sent in JSON as a real Boolean
|
75
|
-
# So runtime check defensively
|
76
|
-
if value is not None:
|
77
|
-
if isinstance(value, bool):
|
78
|
-
return value
|
79
|
-
if value.lower() == "true":
|
80
|
-
return True
|
81
|
-
return False
|
82
|
-
return None
|
83
|
-
|
84
|
-
|
85
|
-
class DateScalar(ScalarDefinition[date]):
|
86
|
-
"""
|
87
|
-
Date Scalar.
|
88
|
-
|
89
|
-
Turn an ISO formatted date like YYYY-MM-dd into a date.
|
90
|
-
"""
|
91
|
-
|
92
|
-
@classmethod
|
93
|
-
def from_str(cls, value: Optional[str]) -> Optional[date]:
|
94
|
-
"""Convert optional str to optional date."""
|
95
|
-
return date.fromisoformat(value) if value is not None else None
|
96
|
-
|
97
|
-
|
98
|
-
class DateTimeScalar(ScalarDefinition[datetime]):
|
99
|
-
"""
|
100
|
-
Date Time Scalar.
|
101
|
-
|
102
|
-
Turn a date time string into datetime.
|
103
|
-
"""
|
104
|
-
|
105
|
-
@classmethod
|
106
|
-
def from_str(cls, value: Optional[str]) -> Optional[datetime]:
|
107
|
-
"""Convert optional str to optional datetime."""
|
108
|
-
return datetime.strptime(value, cls.expected_format()) if value is not None else None
|
109
|
-
|
110
|
-
@staticmethod
|
111
|
-
def expected_format() -> str:
|
112
|
-
"""Return the expected date mask for parsing string to datetime."""
|
113
|
-
return "%Y-%m-%d %I:%M:%S %p"
|
114
|
-
|
115
|
-
|
116
|
-
class IsoDateTimeScalar(ScalarDefinition[datetime]):
|
117
|
-
"""
|
118
|
-
Iso Date Time Scalar.
|
119
|
-
|
120
|
-
Turn a ISO 8601 date time string into datetime. Benchling fields use RFC 3339, unlike app config date times.
|
121
|
-
"""
|
122
|
-
|
123
|
-
@classmethod
|
124
|
-
def from_str(cls, value: Optional[str]) -> Optional[datetime]:
|
125
|
-
"""Convert optional str to optional datetime."""
|
126
|
-
return datetime.fromisoformat(value) if value is not None else None
|
127
|
-
|
128
|
-
|
129
|
-
class FloatScalar(ScalarDefinition[float]):
|
130
|
-
"""
|
131
|
-
Float Scalar.
|
132
|
-
|
133
|
-
Turn a string into float. Assumes the string, if not empty, is a valid floating point.
|
134
|
-
"""
|
135
|
-
|
136
|
-
@classmethod
|
137
|
-
def from_str(cls, value: Optional[str]) -> Optional[float]:
|
138
|
-
"""Convert optional str to optional float."""
|
139
|
-
return float(value) if value is not None else None
|
140
|
-
|
141
|
-
|
142
|
-
class IntScalar(ScalarDefinition[int]):
|
143
|
-
"""
|
144
|
-
Int Scalar.
|
145
|
-
|
146
|
-
Turn a string into int. Assumes the string, if not empty, is a valid integer.
|
147
|
-
"""
|
148
|
-
|
149
|
-
@classmethod
|
150
|
-
def from_str(cls, value: Optional[str]) -> Optional[int]:
|
151
|
-
"""Convert optional str to optional int."""
|
152
|
-
return int(value) if value is not None else None
|
153
|
-
|
154
|
-
|
155
|
-
class JsonScalar(ScalarDefinition[JsonType]):
|
156
|
-
"""
|
157
|
-
Json Scalar.
|
158
|
-
|
159
|
-
Turn a string into JSON. Assumes the string is a valid JSON string.
|
160
|
-
"""
|
161
|
-
|
162
|
-
@classmethod
|
163
|
-
def from_str(cls, value: Optional[str]) -> Optional[JsonType]:
|
164
|
-
"""Convert optional str to optional JsonType."""
|
165
|
-
return json.loads(value) if value is not None else None
|
166
|
-
|
167
|
-
|
168
|
-
class TextScalar(ScalarDefinition[str]):
|
169
|
-
"""
|
170
|
-
Text Scalar.
|
171
|
-
|
172
|
-
Text is already a string, so no conversion is performed.
|
173
|
-
"""
|
174
|
-
|
175
|
-
@classmethod
|
176
|
-
def from_str(cls, value: Optional[str]) -> Optional[str]:
|
177
|
-
"""Convert optional str to optional str. Implemented to appease ScalarDefinition contract."""
|
178
|
-
return value
|
179
|
-
|
180
|
-
|
181
|
-
class SecureTextScalar(TextScalar):
|
182
|
-
"""
|
183
|
-
Secure Text Scalar.
|
184
|
-
|
185
|
-
Text is already a string, so no conversion is performed.
|
186
|
-
"""
|
187
|
-
|
188
|
-
pass
|
189
|
-
|
190
|
-
|
191
|
-
def scalar_definition_from_field_type(field_type: FieldType) -> ScalarDefinition:
|
192
|
-
"""
|
193
|
-
Scalar Definition From Field Type.
|
194
|
-
|
195
|
-
Returns a ScalarDefinition for parsing a typed value given a field type.
|
196
|
-
Assumes TextScalar (string) for any types not specifically enumerated.
|
197
|
-
"""
|
198
|
-
if field_type == field_type.BOOLEAN:
|
199
|
-
return BoolScalar.init()
|
200
|
-
elif field_type == field_type.DATE:
|
201
|
-
return DateScalar.init()
|
202
|
-
elif field_type == field_type.DATETIME:
|
203
|
-
return IsoDateTimeScalar.init()
|
204
|
-
elif field_type == field_type.FLOAT:
|
205
|
-
return FloatScalar.init()
|
206
|
-
elif field_type == field_type.INTEGER:
|
207
|
-
return IntScalar.init()
|
208
|
-
elif field_type == field_type.JSON:
|
209
|
-
return JsonScalar.init()
|
210
|
-
elif field_type == field_type.TEXT:
|
211
|
-
return TextScalar.init()
|
212
|
-
# Assume all other types are str, which is safe for fields
|
213
|
-
return TextScalar.init()
|
214
|
-
|
215
|
-
|
216
|
-
# Maps scalar types from the API into typed Python SDK scalar definitions
|
217
|
-
DEFAULT_SCALAR_DEFINITIONS: Dict[ScalarConfigItemType, ScalarDefinition] = {
|
218
|
-
BooleanAppConfigItemType.BOOLEAN: BoolScalar.init(),
|
219
|
-
DateAppConfigItemType.DATE: DateScalar.init(),
|
220
|
-
DatetimeAppConfigItemType.DATETIME: DateTimeScalar.init(),
|
221
|
-
FloatAppConfigItemType.FLOAT: FloatScalar.init(),
|
222
|
-
IntegerAppConfigItemType.INTEGER: IntScalar.init(),
|
223
|
-
JsonAppConfigItemType.JSON: JsonScalar.init(),
|
224
|
-
SecureTextAppConfigItemType.SECURE_TEXT: SecureTextScalar.init(),
|
225
|
-
TextAppConfigItemType.TEXT: TextScalar.init(),
|
226
|
-
}
|
@@ -1,409 +0,0 @@
|
|
1
|
-
from datetime import date, datetime
|
2
|
-
from typing import List, Optional, Type, Union
|
3
|
-
|
4
|
-
from benchling_api_client.v2.beta.models.app_config_field_type import AppConfigFieldType
|
5
|
-
from benchling_api_client.v2.beta.models.base_manifest_config import BaseManifestConfig
|
6
|
-
from benchling_api_client.v2.beta.models.dropdown_dependency import DropdownDependency
|
7
|
-
from benchling_api_client.v2.beta.models.dropdown_dependency_types import DropdownDependencyTypes
|
8
|
-
from benchling_api_client.v2.beta.models.entity_schema_dependency import EntitySchemaDependency
|
9
|
-
from benchling_api_client.v2.beta.models.entity_schema_dependency_type import EntitySchemaDependencyType
|
10
|
-
from benchling_api_client.v2.beta.models.field_definitions_manifest import FieldDefinitionsManifest
|
11
|
-
from benchling_api_client.v2.beta.models.manifest_array_config import ManifestArrayConfig
|
12
|
-
from benchling_api_client.v2.beta.models.manifest_boolean_scalar_config import ManifestBooleanScalarConfig
|
13
|
-
from benchling_api_client.v2.beta.models.manifest_date_scalar_config import ManifestDateScalarConfig
|
14
|
-
from benchling_api_client.v2.beta.models.manifest_datetime_scalar_config import ManifestDatetimeScalarConfig
|
15
|
-
from benchling_api_client.v2.beta.models.manifest_float_scalar_config import ManifestFloatScalarConfig
|
16
|
-
from benchling_api_client.v2.beta.models.manifest_integer_scalar_config import ManifestIntegerScalarConfig
|
17
|
-
from benchling_api_client.v2.beta.models.manifest_json_scalar_config import ManifestJsonScalarConfig
|
18
|
-
from benchling_api_client.v2.beta.models.manifest_scalar_config import ManifestScalarConfig
|
19
|
-
from benchling_api_client.v2.beta.models.manifest_secure_text_scalar_config import (
|
20
|
-
ManifestSecureTextScalarConfig,
|
21
|
-
)
|
22
|
-
from benchling_api_client.v2.beta.models.manifest_text_scalar_config import ManifestTextScalarConfig
|
23
|
-
from benchling_api_client.v2.beta.models.resource_dependency import ResourceDependency
|
24
|
-
from benchling_api_client.v2.beta.models.resource_dependency_types import ResourceDependencyTypes
|
25
|
-
from benchling_api_client.v2.beta.models.scalar_config import ScalarConfig
|
26
|
-
from benchling_api_client.v2.beta.models.scalar_config_types import ScalarConfigTypes
|
27
|
-
from benchling_api_client.v2.beta.models.schema_dependency import SchemaDependency
|
28
|
-
from benchling_api_client.v2.beta.models.schema_dependency_subtypes import SchemaDependencySubtypes
|
29
|
-
from benchling_api_client.v2.beta.models.schema_dependency_types import SchemaDependencyTypes
|
30
|
-
from benchling_api_client.v2.beta.models.workflow_task_schema_dependency import WorkflowTaskSchemaDependency
|
31
|
-
from benchling_api_client.v2.beta.models.workflow_task_schema_dependency_output import (
|
32
|
-
WorkflowTaskSchemaDependencyOutput,
|
33
|
-
)
|
34
|
-
from benchling_api_client.v2.beta.models.workflow_task_schema_dependency_type import (
|
35
|
-
WorkflowTaskSchemaDependencyType,
|
36
|
-
)
|
37
|
-
from benchling_api_client.v2.extensions import UnknownType
|
38
|
-
from benchling_api_client.v2.stable.extensions import NotPresentError
|
39
|
-
|
40
|
-
from benchling_sdk.apps.config.dependencies import ConfigurationReference, UnsupportedDependencyError
|
41
|
-
from benchling_sdk.apps.config.scalars import JsonType, ScalarModelType
|
42
|
-
from benchling_sdk.models import (
|
43
|
-
AaSequence,
|
44
|
-
ArrayElementAppConfigItem,
|
45
|
-
AssayResult,
|
46
|
-
AssayRun,
|
47
|
-
BooleanAppConfigItem,
|
48
|
-
Box,
|
49
|
-
Container,
|
50
|
-
CustomEntity,
|
51
|
-
DateAppConfigItem,
|
52
|
-
DatetimeAppConfigItem,
|
53
|
-
DnaOligo,
|
54
|
-
DnaSequence,
|
55
|
-
EntitySchemaAppConfigItem,
|
56
|
-
Entry,
|
57
|
-
FieldAppConfigItem,
|
58
|
-
FloatAppConfigItem,
|
59
|
-
GenericApiIdentifiedAppConfigItem,
|
60
|
-
IntegerAppConfigItem,
|
61
|
-
JsonAppConfigItem,
|
62
|
-
Location,
|
63
|
-
Mixture,
|
64
|
-
Molecule,
|
65
|
-
Plate,
|
66
|
-
Request,
|
67
|
-
RnaOligo,
|
68
|
-
RnaSequence,
|
69
|
-
SecureTextAppConfigItem,
|
70
|
-
TextAppConfigItem,
|
71
|
-
WorkflowTask,
|
72
|
-
)
|
73
|
-
|
74
|
-
_MODEL_TYPES_FROM_SCHEMA_TYPE = {
|
75
|
-
SchemaDependencyTypes.CONTAINER_SCHEMA: Container,
|
76
|
-
SchemaDependencyTypes.PLATE_SCHEMA: Plate,
|
77
|
-
SchemaDependencyTypes.BOX_SCHEMA: Box,
|
78
|
-
SchemaDependencyTypes.LOCATION_SCHEMA: Location,
|
79
|
-
SchemaDependencyTypes.ENTRY_SCHEMA: Entry,
|
80
|
-
SchemaDependencyTypes.REQUEST_SCHEMA: Request,
|
81
|
-
SchemaDependencyTypes.RESULT_SCHEMA: AssayResult,
|
82
|
-
SchemaDependencyTypes.RUN_SCHEMA: AssayRun,
|
83
|
-
SchemaDependencyTypes.WORKFLOW_TASK_SCHEMA: WorkflowTask,
|
84
|
-
}
|
85
|
-
|
86
|
-
|
87
|
-
_SCALAR_TYPES_FROM_CONFIG = {
|
88
|
-
ScalarConfigTypes.BOOLEAN: bool,
|
89
|
-
ScalarConfigTypes.DATE: date,
|
90
|
-
ScalarConfigTypes.DATETIME: datetime,
|
91
|
-
ScalarConfigTypes.FLOAT: float,
|
92
|
-
ScalarConfigTypes.INTEGER: int,
|
93
|
-
ScalarConfigTypes.JSON: JsonType,
|
94
|
-
ScalarConfigTypes.TEXT: str,
|
95
|
-
}
|
96
|
-
|
97
|
-
|
98
|
-
_FIELD_SCALAR_TYPES_FROM_CONFIG = {
|
99
|
-
AppConfigFieldType.BOOLEAN: bool,
|
100
|
-
AppConfigFieldType.DATE: date,
|
101
|
-
AppConfigFieldType.DATETIME: datetime,
|
102
|
-
AppConfigFieldType.FLOAT: float,
|
103
|
-
AppConfigFieldType.INTEGER: int,
|
104
|
-
AppConfigFieldType.JSON: JsonType,
|
105
|
-
AppConfigFieldType.TEXT: str,
|
106
|
-
}
|
107
|
-
|
108
|
-
|
109
|
-
ModelType = Union[AssayResult, AssayRun, Box, Container, Entry, Location, Plate, Request]
|
110
|
-
|
111
|
-
_INSTANCE_FROM_SCHEMA_SUBTYPE = {
|
112
|
-
SchemaDependencySubtypes.AA_SEQUENCE: AaSequence,
|
113
|
-
SchemaDependencySubtypes.CUSTOM_ENTITY: CustomEntity,
|
114
|
-
SchemaDependencySubtypes.DNA_SEQUENCE: DnaSequence,
|
115
|
-
SchemaDependencySubtypes.DNA_OLIGO: DnaOligo,
|
116
|
-
SchemaDependencySubtypes.MIXTURE: Mixture,
|
117
|
-
SchemaDependencySubtypes.MOLECULE: Molecule,
|
118
|
-
SchemaDependencySubtypes.RNA_OLIGO: RnaOligo,
|
119
|
-
SchemaDependencySubtypes.RNA_SEQUENCE: RnaSequence,
|
120
|
-
}
|
121
|
-
|
122
|
-
EntitySubtype = Union[
|
123
|
-
AaSequence, CustomEntity, DnaOligo, DnaSequence, Mixture, Molecule, RnaOligo, RnaSequence
|
124
|
-
]
|
125
|
-
|
126
|
-
AnyDependency = Union[
|
127
|
-
BaseManifestConfig,
|
128
|
-
DropdownDependency,
|
129
|
-
EntitySchemaDependency,
|
130
|
-
FieldDefinitionsManifest,
|
131
|
-
ManifestArrayConfig,
|
132
|
-
ManifestScalarConfig,
|
133
|
-
ResourceDependency,
|
134
|
-
SchemaDependency,
|
135
|
-
WorkflowTaskSchemaDependency,
|
136
|
-
]
|
137
|
-
|
138
|
-
ArrayElementDependency = Union[
|
139
|
-
SchemaDependency,
|
140
|
-
EntitySchemaDependency,
|
141
|
-
WorkflowTaskSchemaDependency,
|
142
|
-
DropdownDependency,
|
143
|
-
ResourceDependency,
|
144
|
-
ManifestScalarConfig,
|
145
|
-
]
|
146
|
-
|
147
|
-
|
148
|
-
class UnsupportedSubTypeError(Exception):
|
149
|
-
"""Error when an unsupported subtype is encountered."""
|
150
|
-
|
151
|
-
pass
|
152
|
-
|
153
|
-
|
154
|
-
def model_type_from_dependency(
|
155
|
-
dependency: Union[EntitySchemaDependency, SchemaDependency]
|
156
|
-
) -> Optional[Type[Union[ModelType, EntitySubtype]]]:
|
157
|
-
"""Translate a schema dependency to its model class. Must have a valid subtype."""
|
158
|
-
if isinstance(dependency, EntitySchemaDependency):
|
159
|
-
subtype = subtype_from_entity_schema_dependency(dependency)
|
160
|
-
if subtype:
|
161
|
-
return _subtype_instance_from_dependency(dependency)
|
162
|
-
return None
|
163
|
-
return _MODEL_TYPES_FROM_SCHEMA_TYPE[dependency.type]
|
164
|
-
|
165
|
-
|
166
|
-
def scalar_type_from_config(config: ScalarConfig) -> Union[object, Type[ScalarModelType]]:
|
167
|
-
"""Translate a scalar config to its Pyton type."""
|
168
|
-
# We union with object to satisfy JsonType.
|
169
|
-
return _SCALAR_TYPES_FROM_CONFIG.get(config.type, str)
|
170
|
-
|
171
|
-
|
172
|
-
def scalar_type_from_field_config(config: FieldDefinitionsManifest) -> Union[object, Type[ScalarModelType]]:
|
173
|
-
"""Translate a field config to its Pyton type."""
|
174
|
-
# type may not be specified, so handle NotPresentError
|
175
|
-
try:
|
176
|
-
if hasattr(config, "type"):
|
177
|
-
# We union with object to satisfy JsonType.
|
178
|
-
return _FIELD_SCALAR_TYPES_FROM_CONFIG.get(config.type, str)
|
179
|
-
# We can't seem to handle this programmatically by checking isinstance() or output truthiness
|
180
|
-
except NotPresentError:
|
181
|
-
pass
|
182
|
-
return str
|
183
|
-
|
184
|
-
|
185
|
-
def field_definitions_from_dependency(
|
186
|
-
dependency: Union[
|
187
|
-
EntitySchemaDependency,
|
188
|
-
SchemaDependency,
|
189
|
-
WorkflowTaskSchemaDependency,
|
190
|
-
WorkflowTaskSchemaDependencyOutput,
|
191
|
-
]
|
192
|
-
) -> List[FieldDefinitionsManifest]:
|
193
|
-
"""Safely return a list of field definitions from a schema dependency or empty list."""
|
194
|
-
try:
|
195
|
-
if hasattr(dependency, "field_definitions"):
|
196
|
-
return dependency.field_definitions
|
197
|
-
# We can't seem to handle this programmatically by checking isinstance() or field truthiness
|
198
|
-
except NotPresentError:
|
199
|
-
pass
|
200
|
-
return []
|
201
|
-
|
202
|
-
|
203
|
-
def element_definition_from_dependency(dependency: ManifestArrayConfig) -> List[ArrayElementDependency]:
|
204
|
-
"""Safely return an element definition as a list of dependencies from an array dependency or empty list."""
|
205
|
-
try:
|
206
|
-
if hasattr(dependency, "element_definition"):
|
207
|
-
return [
|
208
|
-
_fix_element_definition_deserialization(element) for element in dependency.element_definition
|
209
|
-
]
|
210
|
-
# We can't seem to handle this programmatically by checking isinstance() or field truthiness
|
211
|
-
except NotPresentError:
|
212
|
-
pass
|
213
|
-
return []
|
214
|
-
|
215
|
-
|
216
|
-
def enum_from_dependency(
|
217
|
-
dependency: Union[
|
218
|
-
ManifestFloatScalarConfig,
|
219
|
-
ManifestIntegerScalarConfig,
|
220
|
-
ManifestTextScalarConfig,
|
221
|
-
]
|
222
|
-
) -> List:
|
223
|
-
"""Safely return an enum from a scalar config."""
|
224
|
-
try:
|
225
|
-
if hasattr(dependency, "enum"):
|
226
|
-
return dependency.enum
|
227
|
-
# We can't seem to handle this programmatically by checking isinstance() or field truthiness
|
228
|
-
except NotPresentError:
|
229
|
-
pass
|
230
|
-
return []
|
231
|
-
|
232
|
-
|
233
|
-
# TODO BNCH-57036 All element definitions currently deserialize to UnknownType. Hack around this temporarily
|
234
|
-
def _fix_element_definition_deserialization(
|
235
|
-
element: Union[UnknownType, ArrayElementDependency]
|
236
|
-
) -> ArrayElementDependency:
|
237
|
-
if isinstance(element, UnknownType):
|
238
|
-
if "type" in element.value:
|
239
|
-
element_type = element.value["type"]
|
240
|
-
if element_type == WorkflowTaskSchemaDependencyType.WORKFLOW_TASK_SCHEMA:
|
241
|
-
return WorkflowTaskSchemaDependency.from_dict(element.value)
|
242
|
-
elif element_type == EntitySchemaDependencyType.ENTITY_SCHEMA:
|
243
|
-
return EntitySchemaDependency.from_dict(element.value)
|
244
|
-
elif element_type in [member.value for member in SchemaDependencyTypes]:
|
245
|
-
return SchemaDependency.from_dict(element.value)
|
246
|
-
elif element_type == DropdownDependencyTypes.DROPDOWN:
|
247
|
-
return DropdownDependency.from_dict(element.value)
|
248
|
-
elif element_type in [member.value for member in ResourceDependencyTypes]:
|
249
|
-
return ResourceDependency.from_dict(element.value)
|
250
|
-
elif element_type in [member.value for member in ScalarConfigTypes]:
|
251
|
-
return type(element_type).from_dict(element.value)
|
252
|
-
raise NotImplementedError(f"No array deserialization fix for {element}")
|
253
|
-
return element
|
254
|
-
|
255
|
-
|
256
|
-
def workflow_task_schema_output_from_dependency(
|
257
|
-
dependency: WorkflowTaskSchemaDependency,
|
258
|
-
) -> Optional[WorkflowTaskSchemaDependencyOutput]:
|
259
|
-
"""Safely return a workflow task schema output from a workflow task schema or None."""
|
260
|
-
try:
|
261
|
-
if hasattr(dependency, "output"):
|
262
|
-
return dependency.output
|
263
|
-
# We can't seem to handle this programmatically by checking isinstance() or output truthiness
|
264
|
-
except NotPresentError:
|
265
|
-
pass
|
266
|
-
return None
|
267
|
-
|
268
|
-
|
269
|
-
def options_from_dependency(dependency: DropdownDependency) -> List[BaseManifestConfig]:
|
270
|
-
"""Safely return a list of options from a dropdown dependency or empty list."""
|
271
|
-
try:
|
272
|
-
if hasattr(dependency, "options"):
|
273
|
-
return dependency.options
|
274
|
-
# We can't seem to handle this programmatically by checking isinstance() or field truthiness
|
275
|
-
except NotPresentError:
|
276
|
-
pass
|
277
|
-
return []
|
278
|
-
|
279
|
-
|
280
|
-
def is_config_required(dependency: AnyDependency) -> bool:
|
281
|
-
"""Safely return if a config item is required."""
|
282
|
-
try:
|
283
|
-
if hasattr(dependency, "required_config"):
|
284
|
-
# `type: ignore` is used here because casting would be inaccurate or fragile.
|
285
|
-
return dependency.required_config # type: ignore
|
286
|
-
# We can't seem to handle this programmatically by checking isinstance() or field truthiness
|
287
|
-
except NotPresentError:
|
288
|
-
pass
|
289
|
-
return False
|
290
|
-
|
291
|
-
|
292
|
-
def is_field_value_required(dependency: FieldDefinitionsManifest) -> bool:
|
293
|
-
"""
|
294
|
-
Safely return if a field must have a value.
|
295
|
-
|
296
|
-
A field must be specified as requiredConfig: true AND isRequired: true to require a value.
|
297
|
-
"""
|
298
|
-
# Fields must be both linked and isRequired to always provide a value
|
299
|
-
try:
|
300
|
-
if hasattr(dependency, "required_config") and hasattr(dependency, "is_required"):
|
301
|
-
# dependency.required_config is Optional so evaluate the bool value
|
302
|
-
return dependency.required_config is True and dependency.is_required is True
|
303
|
-
# We can't seem to handle this programmatically by checking isinstance() or field truthiness
|
304
|
-
except NotPresentError:
|
305
|
-
pass
|
306
|
-
return False
|
307
|
-
|
308
|
-
|
309
|
-
# For forwards compatibility with multi-valued scalars, which could infer Unset == False
|
310
|
-
def is_config_multi_valued(dependency: FieldDefinitionsManifest) -> bool:
|
311
|
-
"""
|
312
|
-
Safely return if a config item is multi-valued.
|
313
|
-
|
314
|
-
Assumes False in the case that a multi-valued constraint is unspecified (Unset).
|
315
|
-
"""
|
316
|
-
multi_valued_unset = is_config_multi_valued_or_unset(dependency)
|
317
|
-
return multi_valued_unset if multi_valued_unset is not None else False
|
318
|
-
|
319
|
-
|
320
|
-
def is_config_multi_valued_or_unset(dependency: FieldDefinitionsManifest) -> Optional[bool]:
|
321
|
-
"""
|
322
|
-
Safely return if a config item is multi-valued or None if it's Unset.
|
323
|
-
|
324
|
-
Multi-valued constraint being undefined cannot be safely inferred for type coercion.
|
325
|
-
|
326
|
-
For instance, a required text field could be typed as:
|
327
|
-
isMulti == True: List[str]
|
328
|
-
isMulti == False: str
|
329
|
-
isMulti == Unset: Union[str, List[str]]
|
330
|
-
"""
|
331
|
-
try:
|
332
|
-
if hasattr(dependency, "is_multi") and dependency.is_multi is not None:
|
333
|
-
return dependency.is_multi
|
334
|
-
# We can't seem to handle this programmatically by checking isinstance() or field truthiness
|
335
|
-
except NotPresentError:
|
336
|
-
pass
|
337
|
-
return None
|
338
|
-
|
339
|
-
|
340
|
-
def subtype_from_entity_schema_dependency(
|
341
|
-
dependency: EntitySchemaDependency,
|
342
|
-
) -> Optional[SchemaDependencySubtypes]:
|
343
|
-
"""Safely return an entity schema dependency's subtype, if present."""
|
344
|
-
try:
|
345
|
-
if hasattr(dependency, "subtype") and dependency.subtype:
|
346
|
-
return dependency.subtype
|
347
|
-
# We can't seem to handle this programmatically by checking isinstance() or field truthiness
|
348
|
-
except NotPresentError:
|
349
|
-
pass
|
350
|
-
return None
|
351
|
-
|
352
|
-
|
353
|
-
def app_config_type_from_dependency(dependency: AnyDependency) -> Type[ConfigurationReference]:
|
354
|
-
"""
|
355
|
-
App Config Item Type From Item.
|
356
|
-
|
357
|
-
Returns the type of the API model corresponding to an app config item.
|
358
|
-
Raises UnsupportedDependencyError if encountering an unknown type.
|
359
|
-
"""
|
360
|
-
# Generic type
|
361
|
-
if isinstance(
|
362
|
-
dependency,
|
363
|
-
(
|
364
|
-
BaseManifestConfig,
|
365
|
-
DropdownDependency,
|
366
|
-
SchemaDependency,
|
367
|
-
ResourceDependency,
|
368
|
-
WorkflowTaskSchemaDependency,
|
369
|
-
),
|
370
|
-
):
|
371
|
-
return GenericApiIdentifiedAppConfigItem
|
372
|
-
# Specially handled Schema types
|
373
|
-
elif isinstance(dependency, FieldDefinitionsManifest):
|
374
|
-
return FieldAppConfigItem
|
375
|
-
elif isinstance(dependency, EntitySchemaDependency):
|
376
|
-
return EntitySchemaAppConfigItem
|
377
|
-
# Scalar types
|
378
|
-
elif isinstance(dependency, ManifestBooleanScalarConfig):
|
379
|
-
return BooleanAppConfigItem
|
380
|
-
elif isinstance(dependency, ManifestDateScalarConfig):
|
381
|
-
return DateAppConfigItem
|
382
|
-
elif isinstance(dependency, ManifestDatetimeScalarConfig):
|
383
|
-
return DatetimeAppConfigItem
|
384
|
-
elif isinstance(dependency, ManifestFloatScalarConfig):
|
385
|
-
return FloatAppConfigItem
|
386
|
-
elif isinstance(dependency, ManifestIntegerScalarConfig):
|
387
|
-
return IntegerAppConfigItem
|
388
|
-
elif isinstance(dependency, ManifestJsonScalarConfig):
|
389
|
-
return JsonAppConfigItem
|
390
|
-
elif isinstance(dependency, ManifestSecureTextScalarConfig):
|
391
|
-
return SecureTextAppConfigItem
|
392
|
-
elif isinstance(dependency, ManifestTextScalarConfig):
|
393
|
-
return TextAppConfigItem
|
394
|
-
# Array type
|
395
|
-
elif isinstance(dependency, ManifestArrayConfig):
|
396
|
-
return ArrayElementAppConfigItem
|
397
|
-
raise UnsupportedDependencyError(f"Unrecognized type for {dependency}]")
|
398
|
-
|
399
|
-
|
400
|
-
def _subtype_instance_from_dependency(dependency: EntitySchemaDependency) -> Type[EntitySubtype]:
|
401
|
-
if dependency.subtype in _INSTANCE_FROM_SCHEMA_SUBTYPE:
|
402
|
-
return _INSTANCE_FROM_SCHEMA_SUBTYPE[dependency.subtype]
|
403
|
-
# This would mean the spec has a new subtype, the manifest installed in Benchling has declared it,
|
404
|
-
# the user has linked it in Benchling, but the app code receiving it was never updated.
|
405
|
-
# App developers should support it in deployed app code before republishing the manifest.
|
406
|
-
raise UnsupportedSubTypeError(
|
407
|
-
f"An unsupported subtype, {dependency.subtype.value} was received. "
|
408
|
-
f"The version of the SDK may need to be upgraded to support this."
|
409
|
-
)
|
File without changes
|
File without changes
|
File without changes
|