benchling-sdk 1.10.0a5__tar.gz → 1.10.0a6__tar.gz
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-1.10.0a5 → benchling_sdk-1.10.0a6}/PKG-INFO +2 -2
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/config/decryption_provider.py +0 -3
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/config/framework.py +12 -11
- benchling_sdk-1.10.0a5/benchling_sdk/apps/helpers/config_helpers.py → benchling_sdk-1.10.0a6/benchling_sdk/apps/config/helpers.py +16 -97
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/config/mock_config.py +68 -69
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/config/types.py +3 -1
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/status/framework.py +1 -21
- benchling_sdk-1.10.0a6/benchling_sdk/apps/status/helpers.py +20 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/status/types.py +1 -1
- benchling_sdk-1.10.0a6/benchling_sdk/services/v2/stable/__init__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/assay_result_service.py +18 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/pyproject.toml +2 -2
- benchling_sdk-1.10.0a5/benchling_sdk/apps/config/__init__.py +0 -3
- benchling_sdk-1.10.0a5/benchling_sdk/apps/config/scalars.py +0 -190
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/LICENSE +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/README.md +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/__init__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/__init__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/canvas/__init__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/canvas/errors.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/canvas/framework.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/canvas/types.py +0 -0
- {benchling_sdk-1.10.0a5/benchling_sdk/apps/helpers → benchling_sdk-1.10.0a6/benchling_sdk/apps/config}/__init__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/config/cryptography_helpers.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/config/errors.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/framework.py +0 -0
- {benchling_sdk-1.10.0a5/benchling_sdk/apps/status → benchling_sdk-1.10.0a6/benchling_sdk/apps/helpers}/__init__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/helpers/manifest_helpers.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/helpers/webhook_helpers.py +0 -0
- {benchling_sdk-1.10.0a5/benchling_sdk/helpers → benchling_sdk-1.10.0a6/benchling_sdk/apps/status}/__init__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/status/errors.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/auth/__init__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/auth/api_key_auth.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/auth/bearer_token_auth.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/auth/client_credentials_oauth2.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/benchling.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/docs/__init__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/docs/__main__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/errors.py +0 -0
- {benchling_sdk-1.10.0a5/benchling_sdk/models/webhooks → benchling_sdk-1.10.0a6/benchling_sdk/helpers}/__init__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/client_helpers.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/constants.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/decorators.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/file_helpers.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/logging_helpers.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/package_helpers.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/pagination_helpers.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/response_helpers.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/retry_helpers.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/serialization_helpers.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/transaction_manager.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/models/__init__.py +0 -0
- {benchling_sdk-1.10.0a5/benchling_sdk/services/v2 → benchling_sdk-1.10.0a6/benchling_sdk/models/webhooks}/__init__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/models/webhooks/v0/__init__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/py.typed +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/__init__.py +0 -0
- {benchling_sdk-1.10.0a5/benchling_sdk/services/v2/alpha → benchling_sdk-1.10.0a6/benchling_sdk/services/v2}/__init__.py +0 -0
- {benchling_sdk-1.10.0a5/benchling_sdk/services/v2/beta → benchling_sdk-1.10.0a6/benchling_sdk/services/v2/alpha}/__init__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/alpha/v2_alpha_app_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/alpha/v2_alpha_dna_sequence_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/base_service.py +0 -0
- {benchling_sdk-1.10.0a5/benchling_sdk/services/v2/stable → benchling_sdk-1.10.0a6/benchling_sdk/services/v2/beta}/__init__.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_aa_sequence_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_app_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_collaboration_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_custom_entity_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_dataset_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_dna_oligo_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_dna_sequence_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_entity_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_entry_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_folder_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_project_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_rna_oligo_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_worklist_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/aa_sequence_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/api_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/app_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/assay_run_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/blob_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/box_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/container_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/custom_entity_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/custom_notation_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/dna_alignments_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/dna_oligo_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/dna_sequence_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/dropdown_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/entry_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/event_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/export_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/feature_library_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/folder_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/inventory_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/lab_automation_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/label_template_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/location_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/mixture_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/molecule_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/nucleotide_alignments_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/oligo_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/organization_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/plate_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/printer_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/project_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/registry_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/request_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/rna_oligo_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/rna_sequence_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/schema_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/task_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/team_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/user_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/warehouse_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/workflow_output_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/workflow_task_group_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/workflow_task_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/v2_alpha_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/v2_beta_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/v2_stable_service.py +0 -0
- {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2_service.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: benchling-sdk
|
3
|
-
Version: 1.10.
|
3
|
+
Version: 1.10.0a6
|
4
4
|
Summary: SDK for interacting with the Benchling Platform.
|
5
5
|
License: Apache-2.0
|
6
6
|
Author: Benchling Support
|
@@ -17,7 +17,7 @@ Provides-Extra: python-jose
|
|
17
17
|
Requires-Dist: PyYAML (>=6.0,<7.0)
|
18
18
|
Requires-Dist: attrs (>=20.1.0,<23)
|
19
19
|
Requires-Dist: backoff (>=1.10.0,<2.0.0)
|
20
|
-
Requires-Dist: benchling-api-client (==2.0.
|
20
|
+
Requires-Dist: benchling-api-client (==2.0.241)
|
21
21
|
Requires-Dist: certifi (>=2022.12.7)
|
22
22
|
Requires-Dist: cryptography (>=41.0.3,<42.0.0) ; extra == "cryptography"
|
23
23
|
Requires-Dist: dataclasses-json (>=0.5.2,<0.6.0)
|
{benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/config/decryption_provider.py
RENAMED
@@ -11,9 +11,6 @@ class BaseDecryptionProvider(ABC):
|
|
11
11
|
Various implementations might use AWS KMS, Azure, etc.
|
12
12
|
"""
|
13
13
|
|
14
|
-
# TODO BNCH-52772 should we loosen this method to accept None and not attempt decryption,
|
15
|
-
# now that config is no longer type safe?
|
16
|
-
|
17
14
|
@abstractmethod
|
18
15
|
def decrypt(self, ciphertext: str) -> str:
|
19
16
|
"""
|
@@ -77,7 +77,8 @@ class BenchlingConfigProvider(ConfigProvider):
|
|
77
77
|
|
78
78
|
# Eager load all config items for now since we don't yet have a way of lazily querying by path
|
79
79
|
all_config_pages = list(app_pages)
|
80
|
-
# Punt on UnknownType for now as apps using manifests with new types +
|
80
|
+
# Punt on UnknownType for now as apps using manifests with new types +
|
81
|
+
# older client could lead to unpredictable results
|
81
82
|
all_config_items = [
|
82
83
|
_supported_config_item(config_item) for page in all_config_pages for config_item in page
|
83
84
|
]
|
@@ -220,13 +221,13 @@ class ConfigItemStore:
|
|
220
221
|
"""
|
221
222
|
Dependency Link Store.
|
222
223
|
|
223
|
-
Marshals an app configuration from the configuration provider into an
|
224
|
+
Marshals an app configuration from the configuration provider into an indexed structure.
|
224
225
|
Only retrieves app configuration once unless its cache is invalidated.
|
225
226
|
"""
|
226
227
|
|
227
228
|
_configuration_provider: ConfigProvider
|
228
229
|
_configuration: Optional[List[ConfigurationReference]] = None
|
229
|
-
|
230
|
+
_configuration_dict: Optional[Dict[ConfigItemPath, ConfigItemWrapper]] = None
|
230
231
|
_array_path_row_names: Dict[Tuple[str, ...], OrderedSet[str]] = dict()
|
231
232
|
|
232
233
|
def __init__(self, configuration_provider: ConfigProvider):
|
@@ -252,17 +253,17 @@ class ConfigItemStore:
|
|
252
253
|
return self._configuration
|
253
254
|
|
254
255
|
@property
|
255
|
-
def
|
256
|
+
def configuration_path_dict(self) -> Dict[ConfigItemPath, ConfigItemWrapper]:
|
256
257
|
"""
|
257
258
|
Config links.
|
258
259
|
|
259
|
-
Return a
|
260
|
+
Return a dict of configuration item paths to their corresponding configuration items.
|
260
261
|
"""
|
261
|
-
if not self.
|
262
|
-
self.
|
262
|
+
if not self._configuration_dict:
|
263
|
+
self._configuration_dict = {
|
263
264
|
tuple(item.path): ConfigItemWrapper(item, item.path) for item in self.configuration
|
264
265
|
}
|
265
|
-
return self.
|
266
|
+
return self._configuration_dict
|
266
267
|
|
267
268
|
def config_by_path(self, path: List[str]) -> ConfigItemWrapper:
|
268
269
|
"""
|
@@ -272,7 +273,7 @@ class ConfigItemStore:
|
|
272
273
|
"""
|
273
274
|
# Since we eager load all config now, we know that missing path means it's not configured in Benchling
|
274
275
|
# Later if we support lazy loading, we'll need to differentiate what's in our cache versus missing
|
275
|
-
return self.
|
276
|
+
return self.configuration_path_dict.get(tuple(path), ConfigItemWrapper(None, path))
|
276
277
|
|
277
278
|
def config_keys_by_path(self, path: List[str]) -> OrderedSet[str]:
|
278
279
|
"""
|
@@ -296,7 +297,7 @@ class ConfigItemStore:
|
|
296
297
|
self._array_path_row_names[path_tuple] = OrderedSet(
|
297
298
|
[
|
298
299
|
config_item.path[len(path)]
|
299
|
-
# Use the list instead of
|
300
|
+
# Use the list instead of configuration_dict to preserve order
|
300
301
|
for config_item in self.configuration
|
301
302
|
# The +1 is the name of the array row
|
302
303
|
if len(config_item.path) >= len(path) + 1
|
@@ -330,7 +331,7 @@ class ConfigItemStore:
|
|
330
331
|
Will force retrieval of configuration from the ConfigProvider the next time the link store is accessed.
|
331
332
|
"""
|
332
333
|
self._configuration = None
|
333
|
-
self.
|
334
|
+
self._configuration_dict = None
|
334
335
|
self._array_path_row_names = dict()
|
335
336
|
|
336
337
|
|
@@ -1,7 +1,6 @@
|
|
1
|
-
from datetime import
|
1
|
+
from datetime import datetime
|
2
2
|
from typing import List, Optional, Union
|
3
3
|
|
4
|
-
from benchling_api_client.v2.beta.models.app_config_field_type import AppConfigFieldType
|
5
4
|
from benchling_api_client.v2.beta.models.base_manifest_config import BaseManifestConfig
|
6
5
|
from benchling_api_client.v2.beta.models.dropdown_dependency import DropdownDependency
|
7
6
|
from benchling_api_client.v2.beta.models.dropdown_dependency_types import DropdownDependencyTypes
|
@@ -29,92 +28,7 @@ from benchling_api_client.v2.beta.models.workflow_task_schema_dependency_type im
|
|
29
28
|
from benchling_api_client.v2.extensions import UnknownType
|
30
29
|
from benchling_api_client.v2.stable.extensions import NotPresentError
|
31
30
|
|
32
|
-
|
33
|
-
from benchling_sdk.models import (
|
34
|
-
AaSequence,
|
35
|
-
AssayResult,
|
36
|
-
AssayRun,
|
37
|
-
Box,
|
38
|
-
Container,
|
39
|
-
CustomEntity,
|
40
|
-
DnaOligo,
|
41
|
-
DnaSequence,
|
42
|
-
Entry,
|
43
|
-
Location,
|
44
|
-
Mixture,
|
45
|
-
Molecule,
|
46
|
-
Plate,
|
47
|
-
Request,
|
48
|
-
RnaOligo,
|
49
|
-
RnaSequence,
|
50
|
-
WorkflowTask,
|
51
|
-
)
|
52
|
-
|
53
|
-
_MODEL_TYPES_FROM_SCHEMA_TYPE = {
|
54
|
-
SchemaDependencyTypes.CONTAINER_SCHEMA: Container,
|
55
|
-
SchemaDependencyTypes.PLATE_SCHEMA: Plate,
|
56
|
-
SchemaDependencyTypes.BOX_SCHEMA: Box,
|
57
|
-
SchemaDependencyTypes.LOCATION_SCHEMA: Location,
|
58
|
-
SchemaDependencyTypes.ENTRY_SCHEMA: Entry,
|
59
|
-
SchemaDependencyTypes.REQUEST_SCHEMA: Request,
|
60
|
-
SchemaDependencyTypes.RESULT_SCHEMA: AssayResult,
|
61
|
-
SchemaDependencyTypes.RUN_SCHEMA: AssayRun,
|
62
|
-
SchemaDependencyTypes.WORKFLOW_TASK_SCHEMA: WorkflowTask,
|
63
|
-
}
|
64
|
-
|
65
|
-
|
66
|
-
_SCALAR_TYPES_FROM_CONFIG = {
|
67
|
-
ScalarConfigTypes.BOOLEAN: bool,
|
68
|
-
ScalarConfigTypes.DATE: date,
|
69
|
-
ScalarConfigTypes.DATETIME: datetime,
|
70
|
-
ScalarConfigTypes.FLOAT: float,
|
71
|
-
ScalarConfigTypes.INTEGER: int,
|
72
|
-
ScalarConfigTypes.JSON: JsonType,
|
73
|
-
ScalarConfigTypes.TEXT: str,
|
74
|
-
}
|
75
|
-
|
76
|
-
|
77
|
-
_FIELD_SCALAR_TYPES_FROM_CONFIG = {
|
78
|
-
AppConfigFieldType.BOOLEAN: bool,
|
79
|
-
AppConfigFieldType.DATE: date,
|
80
|
-
AppConfigFieldType.DATETIME: datetime,
|
81
|
-
AppConfigFieldType.FLOAT: float,
|
82
|
-
AppConfigFieldType.INTEGER: int,
|
83
|
-
AppConfigFieldType.JSON: JsonType,
|
84
|
-
AppConfigFieldType.TEXT: str,
|
85
|
-
}
|
86
|
-
|
87
|
-
|
88
|
-
ModelType = Union[AssayResult, AssayRun, Box, Container, Entry, Location, Plate, Request]
|
89
|
-
|
90
|
-
_INSTANCE_FROM_SCHEMA_SUBTYPE = {
|
91
|
-
SchemaDependencySubtypes.AA_SEQUENCE: AaSequence,
|
92
|
-
SchemaDependencySubtypes.CUSTOM_ENTITY: CustomEntity,
|
93
|
-
SchemaDependencySubtypes.DNA_SEQUENCE: DnaSequence,
|
94
|
-
SchemaDependencySubtypes.DNA_OLIGO: DnaOligo,
|
95
|
-
SchemaDependencySubtypes.MIXTURE: Mixture,
|
96
|
-
SchemaDependencySubtypes.MOLECULE: Molecule,
|
97
|
-
SchemaDependencySubtypes.RNA_OLIGO: RnaOligo,
|
98
|
-
SchemaDependencySubtypes.RNA_SEQUENCE: RnaSequence,
|
99
|
-
}
|
100
|
-
|
101
|
-
EntitySubtype = Union[
|
102
|
-
AaSequence, CustomEntity, DnaOligo, DnaSequence, Mixture, Molecule, RnaOligo, RnaSequence
|
103
|
-
]
|
104
|
-
|
105
|
-
AnyDependency = Union[
|
106
|
-
BaseManifestConfig,
|
107
|
-
DropdownDependency,
|
108
|
-
EntitySchemaDependency,
|
109
|
-
FieldDefinitionsManifest,
|
110
|
-
ManifestArrayConfig,
|
111
|
-
ManifestScalarConfig,
|
112
|
-
ResourceDependency,
|
113
|
-
SchemaDependency,
|
114
|
-
WorkflowTaskSchemaDependency,
|
115
|
-
]
|
116
|
-
|
117
|
-
ArrayElementDependency = Union[
|
31
|
+
_ArrayElementDependency = Union[
|
118
32
|
SchemaDependency,
|
119
33
|
EntitySchemaDependency,
|
120
34
|
WorkflowTaskSchemaDependency,
|
@@ -124,13 +38,13 @@ ArrayElementDependency = Union[
|
|
124
38
|
]
|
125
39
|
|
126
40
|
|
127
|
-
class
|
41
|
+
class _UnsupportedSubTypeError(Exception):
|
128
42
|
"""Error when an unsupported subtype is encountered."""
|
129
43
|
|
130
44
|
pass
|
131
45
|
|
132
46
|
|
133
|
-
def
|
47
|
+
def _field_definitions_from_dependency(
|
134
48
|
dependency: Union[
|
135
49
|
EntitySchemaDependency,
|
136
50
|
SchemaDependency,
|
@@ -148,7 +62,7 @@ def field_definitions_from_dependency(
|
|
148
62
|
return []
|
149
63
|
|
150
64
|
|
151
|
-
def
|
65
|
+
def _element_definition_from_dependency(dependency: ManifestArrayConfig) -> List[_ArrayElementDependency]:
|
152
66
|
"""Safely return an element definition as a list of dependencies from an array dependency or empty list."""
|
153
67
|
try:
|
154
68
|
if hasattr(dependency, "element_definition"):
|
@@ -161,7 +75,7 @@ def element_definition_from_dependency(dependency: ManifestArrayConfig) -> List[
|
|
161
75
|
return []
|
162
76
|
|
163
77
|
|
164
|
-
def
|
78
|
+
def _enum_from_dependency(
|
165
79
|
dependency: Union[
|
166
80
|
ManifestFloatScalarConfig,
|
167
81
|
ManifestIntegerScalarConfig,
|
@@ -180,8 +94,8 @@ def enum_from_dependency(
|
|
180
94
|
|
181
95
|
# TODO BNCH-57036 All element definitions currently deserialize to UnknownType. Hack around this temporarily
|
182
96
|
def _fix_element_definition_deserialization(
|
183
|
-
element: Union[UnknownType,
|
184
|
-
) ->
|
97
|
+
element: Union[UnknownType, _ArrayElementDependency]
|
98
|
+
) -> _ArrayElementDependency:
|
185
99
|
if isinstance(element, UnknownType):
|
186
100
|
if "type" in element.value:
|
187
101
|
element_type = element.value["type"]
|
@@ -201,7 +115,7 @@ def _fix_element_definition_deserialization(
|
|
201
115
|
return element
|
202
116
|
|
203
117
|
|
204
|
-
def
|
118
|
+
def _workflow_task_schema_output_from_dependency(
|
205
119
|
dependency: WorkflowTaskSchemaDependency,
|
206
120
|
) -> Optional[WorkflowTaskSchemaDependencyOutput]:
|
207
121
|
"""Safely return a workflow task schema output from a workflow task schema or None."""
|
@@ -214,7 +128,7 @@ def workflow_task_schema_output_from_dependency(
|
|
214
128
|
return None
|
215
129
|
|
216
130
|
|
217
|
-
def
|
131
|
+
def _options_from_dependency(dependency: DropdownDependency) -> List[BaseManifestConfig]:
|
218
132
|
"""Safely return a list of options from a dropdown dependency or empty list."""
|
219
133
|
try:
|
220
134
|
if hasattr(dependency, "options"):
|
@@ -225,7 +139,7 @@ def options_from_dependency(dependency: DropdownDependency) -> List[BaseManifest
|
|
225
139
|
return []
|
226
140
|
|
227
141
|
|
228
|
-
def
|
142
|
+
def _subtype_from_entity_schema_dependency(
|
229
143
|
dependency: EntitySchemaDependency,
|
230
144
|
) -> Optional[SchemaDependencySubtypes]:
|
231
145
|
"""Safely return an entity schema dependency's subtype, if present."""
|
@@ -236,3 +150,8 @@ def subtype_from_entity_schema_dependency(
|
|
236
150
|
except NotPresentError:
|
237
151
|
pass
|
238
152
|
return None
|
153
|
+
|
154
|
+
|
155
|
+
def datetime_config_value_to_str(value: datetime) -> str:
|
156
|
+
"""Convert a datetime value to a valid string accepted by a datetime app config item."""
|
157
|
+
return value.strftime("%Y-%m-%d %I:%M:%S %p")
|
@@ -4,7 +4,7 @@ from datetime import date, datetime
|
|
4
4
|
import json
|
5
5
|
import random
|
6
6
|
import string
|
7
|
-
from typing import Dict, get_args, List, Optional, Protocol,
|
7
|
+
from typing import cast, Dict, get_args, List, Optional, Protocol, Union
|
8
8
|
|
9
9
|
from benchling_api_client.v2.beta.models.base_manifest_config import BaseManifestConfig
|
10
10
|
from benchling_api_client.v2.beta.models.benchling_app_manifest import BenchlingAppManifest
|
@@ -34,29 +34,19 @@ from benchling_api_client.v2.extensions import UnknownType
|
|
34
34
|
from benchling_api_client.v2.stable.types import UNSET, Unset
|
35
35
|
|
36
36
|
from benchling_sdk.apps.config.decryption_provider import BaseDecryptionProvider
|
37
|
+
from benchling_sdk.apps.config.errors import UnsupportedConfigItemError
|
37
38
|
from benchling_sdk.apps.config.framework import _supported_config_item, ConfigItemStore, StaticConfigProvider
|
38
|
-
from benchling_sdk.apps.config.
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
ScalarDefinition,
|
47
|
-
ScalarType,
|
48
|
-
SecureTextScalar,
|
49
|
-
TextScalar,
|
50
|
-
)
|
51
|
-
from benchling_sdk.apps.config.types import ConfigurationReference
|
52
|
-
from benchling_sdk.apps.helpers.config_helpers import (
|
53
|
-
element_definition_from_dependency,
|
54
|
-
enum_from_dependency,
|
55
|
-
field_definitions_from_dependency,
|
56
|
-
options_from_dependency,
|
57
|
-
subtype_from_entity_schema_dependency,
|
58
|
-
workflow_task_schema_output_from_dependency,
|
39
|
+
from benchling_sdk.apps.config.helpers import (
|
40
|
+
_element_definition_from_dependency,
|
41
|
+
_enum_from_dependency,
|
42
|
+
_field_definitions_from_dependency,
|
43
|
+
_options_from_dependency,
|
44
|
+
_subtype_from_entity_schema_dependency,
|
45
|
+
_workflow_task_schema_output_from_dependency,
|
46
|
+
datetime_config_value_to_str,
|
59
47
|
)
|
48
|
+
from benchling_sdk.apps.config.types import ConfigurationReference, JsonType
|
49
|
+
from benchling_sdk.helpers.logging_helpers import log_stability_warning, StabilityLevel
|
60
50
|
from benchling_sdk.models import (
|
61
51
|
AppConfigItem,
|
62
52
|
ArrayElementAppConfigItem,
|
@@ -98,6 +88,8 @@ ManifestDependencies = Union[
|
|
98
88
|
UnknownType,
|
99
89
|
]
|
100
90
|
|
91
|
+
log_stability_warning(StabilityLevel.BETA)
|
92
|
+
|
101
93
|
|
102
94
|
class MockDecryptionFunction(Protocol):
|
103
95
|
"""Mock out a decryption function for use with secure text."""
|
@@ -296,7 +288,7 @@ def mock_datetime_app_config_item(path: List[str], value: Optional[datetime]) ->
|
|
296
288
|
"""Mock a datetime app config item with a path and specified value."""
|
297
289
|
return DatetimeAppConfigItem(
|
298
290
|
path=path,
|
299
|
-
value=value
|
291
|
+
value=datetime_config_value_to_str(value) if value else None,
|
300
292
|
type=DatetimeAppConfigItemType.DATETIME,
|
301
293
|
id=_random_string("aci_"),
|
302
294
|
)
|
@@ -354,9 +346,10 @@ def mock_text_app_config_item(path: List[str], value: Optional[str]) -> TextAppC
|
|
354
346
|
|
355
347
|
def _mock_dependency(
|
356
348
|
dependency: ManifestDependencies,
|
357
|
-
parent_path: List[str] =
|
349
|
+
parent_path: Optional[List[str]] = None,
|
358
350
|
) -> List[AppConfigItem]:
|
359
351
|
"""Mock a dependency from its manifest definition."""
|
352
|
+
parent_path = parent_path if parent_path else []
|
360
353
|
# MyPy has trouble inferring lists with [config_item] + sub_items so use the syntax like:
|
361
354
|
# [*[config_item], *sub_items]
|
362
355
|
# See https://github.com/python/mypy/issues/3933#issuecomment-808739063
|
@@ -371,12 +364,12 @@ def _mock_dependency(
|
|
371
364
|
)
|
372
365
|
sub_items = [
|
373
366
|
_mock_subdependency(subdependency, dependency, parent_path=parent_path)
|
374
|
-
for subdependency in
|
367
|
+
for subdependency in _options_from_dependency(dependency)
|
375
368
|
]
|
376
369
|
return [*[config_item], *sub_items]
|
377
370
|
elif isinstance(dependency, EntitySchemaDependency):
|
378
371
|
linked_resource_id = _random_string("val_")
|
379
|
-
subtype =
|
372
|
+
subtype = _subtype_from_entity_schema_dependency(dependency)
|
380
373
|
optional_subtype: Union[SchemaDependencySubtypes, Unset] = (
|
381
374
|
_convert_entity_subtype(subtype) if subtype is not None else UNSET
|
382
375
|
)
|
@@ -390,7 +383,7 @@ def _mock_dependency(
|
|
390
383
|
)
|
391
384
|
sub_items = [
|
392
385
|
_mock_subdependency(subdependency, dependency, parent_path=parent_path)
|
393
|
-
for subdependency in
|
386
|
+
for subdependency in _field_definitions_from_dependency(dependency)
|
394
387
|
]
|
395
388
|
return [*[entity_item], *sub_items]
|
396
389
|
elif isinstance(dependency, SchemaDependency):
|
@@ -404,7 +397,7 @@ def _mock_dependency(
|
|
404
397
|
)
|
405
398
|
sub_items = [
|
406
399
|
_mock_subdependency(subdependency, dependency, parent_path=parent_path)
|
407
|
-
for subdependency in
|
400
|
+
for subdependency in _field_definitions_from_dependency(dependency)
|
408
401
|
]
|
409
402
|
return [*[config_item], *sub_items]
|
410
403
|
elif isinstance(dependency, WorkflowTaskSchemaDependency):
|
@@ -418,11 +411,11 @@ def _mock_dependency(
|
|
418
411
|
)
|
419
412
|
sub_items = [
|
420
413
|
_mock_subdependency(subdependency, dependency, parent_path=parent_path)
|
421
|
-
for subdependency in
|
414
|
+
for subdependency in _field_definitions_from_dependency(dependency)
|
422
415
|
]
|
423
|
-
workflow_task_output =
|
416
|
+
workflow_task_output = _workflow_task_schema_output_from_dependency(dependency)
|
424
417
|
if workflow_task_output:
|
425
|
-
output_fields =
|
418
|
+
output_fields = _field_definitions_from_dependency(workflow_task_output)
|
426
419
|
output_items = [
|
427
420
|
_mock_workflow_output_subdependency(subdependency, dependency, parent_path=parent_path)
|
428
421
|
for subdependency in output_fields
|
@@ -458,39 +451,40 @@ def _convert_entity_subtype(manifest_subtype: SchemaDependencySubtypesBeta) -> S
|
|
458
451
|
|
459
452
|
|
460
453
|
def _mock_scalar_dependency(
|
461
|
-
dependency: ManifestScalarConfig, parent_path: List[str] =
|
454
|
+
dependency: ManifestScalarConfig, parent_path: Optional[List[str]] = None
|
462
455
|
) -> AppConfigItem:
|
456
|
+
parent_path = parent_path if parent_path else []
|
463
457
|
if isinstance(dependency, ManifestBooleanScalarConfig):
|
464
|
-
bool_value =
|
458
|
+
bool_value = cast(bool, _mock_scalar_value(dependency))
|
465
459
|
bool_config = mock_bool_app_config_item([dependency.name], bool_value)
|
466
460
|
return _append_config_item_path(bool_config, parent_path)
|
467
461
|
elif isinstance(dependency, ManifestDateScalarConfig):
|
468
|
-
date_value =
|
462
|
+
date_value = cast(date, _mock_scalar_value(dependency))
|
469
463
|
date_config = mock_date_app_config_item([dependency.name], date_value)
|
470
464
|
return _append_config_item_path(date_config, parent_path)
|
471
465
|
elif isinstance(dependency, ManifestDatetimeScalarConfig):
|
472
|
-
datetime_value =
|
466
|
+
datetime_value = cast(datetime, _mock_scalar_value(dependency))
|
473
467
|
datetime_config = mock_datetime_app_config_item([dependency.name], datetime_value)
|
474
468
|
return _append_config_item_path(datetime_config, parent_path)
|
475
469
|
elif isinstance(dependency, ManifestFloatScalarConfig):
|
476
|
-
float_value =
|
470
|
+
float_value = cast(float, _mock_scalar_value(dependency))
|
477
471
|
float_config = mock_float_app_config_item([dependency.name], float_value)
|
478
472
|
return _append_config_item_path(float_config, parent_path)
|
479
473
|
elif isinstance(dependency, ManifestIntegerScalarConfig):
|
480
|
-
int_value =
|
474
|
+
int_value = cast(int, _mock_scalar_value(dependency))
|
481
475
|
int_config = mock_int_app_config_item([dependency.name], int_value)
|
482
476
|
return _append_config_item_path(int_config, parent_path)
|
483
477
|
elif isinstance(dependency, ManifestJsonScalarConfig):
|
484
|
-
json_value =
|
478
|
+
json_value = cast(JsonType, _mock_scalar_value(dependency))
|
485
479
|
json_config = mock_json_app_config_item([dependency.name], json_value)
|
486
480
|
return _append_config_item_path(json_config, parent_path)
|
487
481
|
elif isinstance(dependency, ManifestSecureTextScalarConfig):
|
488
|
-
secure_text_value =
|
482
|
+
secure_text_value = cast(str, _mock_scalar_value(dependency))
|
489
483
|
secure_text_config = mock_secure_text_app_config_item([dependency.name], secure_text_value)
|
490
484
|
return _append_config_item_path(secure_text_config, parent_path)
|
491
485
|
else:
|
492
486
|
assert not isinstance(dependency, UnknownType), f"Unable to mock unknown type {dependency}"
|
493
|
-
text_value =
|
487
|
+
text_value = cast(str, _mock_scalar_value(dependency))
|
494
488
|
text_config = mock_text_app_config_item([dependency.name], text_value)
|
495
489
|
return _append_config_item_path(text_config, parent_path)
|
496
490
|
|
@@ -503,12 +497,13 @@ def _append_config_item_path(config_item: AppConfigItem, parent_path: List[str])
|
|
503
497
|
|
504
498
|
|
505
499
|
def _mock_array_dependency(
|
506
|
-
dependency: ManifestArrayConfig, parent_path: List[str] =
|
500
|
+
dependency: ManifestArrayConfig, parent_path: Optional[List[str]] = None, rows: int = 1
|
507
501
|
) -> List[AppConfigItem]:
|
508
502
|
config_rows = []
|
503
|
+
parent_path = parent_path if parent_path else []
|
509
504
|
for i in range(rows):
|
510
505
|
row = _mock_array_row(dependency, parent_path=parent_path)
|
511
|
-
elements =
|
506
|
+
elements = _element_definition_from_dependency(dependency)
|
512
507
|
element_configs = [_mock_dependency(element, row.path) for element in elements]
|
513
508
|
flattened_configs = [element for sublist in element_configs for element in sublist]
|
514
509
|
config_rows.append(row)
|
@@ -516,8 +511,9 @@ def _mock_array_dependency(
|
|
516
511
|
return config_rows
|
517
512
|
|
518
513
|
|
519
|
-
def _mock_array_row(dependency: ManifestArrayConfig, parent_path: List[str] =
|
514
|
+
def _mock_array_row(dependency: ManifestArrayConfig, parent_path: Optional[List[str]] = None):
|
520
515
|
row_name = _random_string("Row ")
|
516
|
+
parent_path = parent_path if parent_path else []
|
521
517
|
return ArrayElementAppConfigItem(
|
522
518
|
id=_random_string("aci_"),
|
523
519
|
path=parent_path + [dependency.name, row_name],
|
@@ -526,25 +522,16 @@ def _mock_array_row(dependency: ManifestArrayConfig, parent_path: List[str] = li
|
|
526
522
|
)
|
527
523
|
|
528
524
|
|
529
|
-
def
|
530
|
-
dependency: ManifestScalarConfig, scalar_definition_type: Type[ScalarDefinition[ScalarType]]
|
531
|
-
) -> Optional[ScalarType]:
|
532
|
-
assert not isinstance(dependency, UnknownType), f"Unable to mock unknown type {dependency}"
|
533
|
-
# These types should be equivalent and this appeases MyPy
|
534
|
-
mocked_value_type = ScalarConfigTypes(dependency.type)
|
535
|
-
mocked_value_str = (
|
536
|
-
_mock_scalar_with_enum(dependency)
|
537
|
-
if _is_scalar_with_enum(dependency)
|
538
|
-
else _mock_scalar_value(mocked_value_type)
|
539
|
-
)
|
540
|
-
return scalar_definition_type.from_str(mocked_value_str)
|
541
|
-
|
542
|
-
|
543
|
-
def _mock_scalar_with_enum(dependency: ManifestScalarConfig) -> str:
|
525
|
+
def _mock_scalar_with_enum(dependency: ManifestScalarConfig) -> Union[float, int, str]:
|
544
526
|
assert isinstance(
|
545
527
|
dependency, (ManifestFloatScalarConfig, ManifestIntegerScalarConfig, ManifestTextScalarConfig)
|
546
528
|
)
|
547
|
-
|
529
|
+
value = random.choice(dependency.enum)
|
530
|
+
if isinstance(dependency, ManifestFloatScalarConfig):
|
531
|
+
return cast(float, value)
|
532
|
+
elif isinstance(dependency, ManifestIntegerScalarConfig):
|
533
|
+
return cast(int, value)
|
534
|
+
return str(value)
|
548
535
|
|
549
536
|
|
550
537
|
def _is_scalar_with_enum(dependency: ManifestScalarConfig) -> bool:
|
@@ -552,15 +539,16 @@ def _is_scalar_with_enum(dependency: ManifestScalarConfig) -> bool:
|
|
552
539
|
dependency, (ManifestFloatScalarConfig, ManifestIntegerScalarConfig, ManifestTextScalarConfig)
|
553
540
|
):
|
554
541
|
# MyPy doesn't find this to be truthy without a specific len check
|
555
|
-
return len(
|
542
|
+
return len(_enum_from_dependency(dependency)) > 0
|
556
543
|
return False
|
557
544
|
|
558
545
|
|
559
546
|
def _mock_subdependency(
|
560
547
|
subdependency: Union[BaseManifestConfig, FieldDefinitionsManifest],
|
561
548
|
parent_config,
|
562
|
-
parent_path: List[str] =
|
549
|
+
parent_path: Optional[List[str]] = None,
|
563
550
|
) -> AppConfigItem:
|
551
|
+
parent_path = parent_path if parent_path else []
|
564
552
|
if isinstance(parent_config, DropdownDependency):
|
565
553
|
linked_resource_id = _random_string("opt_")
|
566
554
|
return GenericApiIdentifiedAppConfigItem(
|
@@ -587,8 +575,9 @@ def _mock_subdependency(
|
|
587
575
|
def _mock_workflow_output_subdependency(
|
588
576
|
subdependency: Union[BaseManifestConfig, FieldDefinitionsManifest],
|
589
577
|
parent_config,
|
590
|
-
parent_path: List[str] =
|
578
|
+
parent_path: Optional[List[str]] = None,
|
591
579
|
) -> AppConfigItem:
|
580
|
+
parent_path = parent_path if parent_path else []
|
592
581
|
linked_resource_id = _random_string("tsf_")
|
593
582
|
app_config = FieldAppConfigItem(
|
594
583
|
id=_random_string("aci_"),
|
@@ -604,18 +593,28 @@ def _mock_linked_resource(id: str, name: Optional[str] = None) -> LinkedAppConfi
|
|
604
593
|
return LinkedAppConfigResourceSummary(id=id, name=name if name else _random_string("Resource Name"))
|
605
594
|
|
606
595
|
|
607
|
-
def _mock_scalar_value(
|
596
|
+
def _mock_scalar_value(
|
597
|
+
dependency: ManifestScalarConfig,
|
598
|
+
) -> Union[bool, date, datetime, int, float, str, Dict[str, Union[str, float]]]:
|
608
599
|
"""Mock a scalar config value from its manifest definition."""
|
609
|
-
if
|
610
|
-
|
600
|
+
if isinstance(dependency, UnknownType):
|
601
|
+
raise UnsupportedConfigItemError(
|
602
|
+
f"Unable to mock scalar value for unsupported dependency type {dependency}"
|
603
|
+
)
|
604
|
+
# These types should be equivalent and this appeases MyPy
|
605
|
+
scalar_type = ScalarConfigTypes(dependency.type)
|
606
|
+
if _is_scalar_with_enum(dependency):
|
607
|
+
return _mock_scalar_with_enum(dependency)
|
608
|
+
elif scalar_type == scalar_type.BOOLEAN:
|
609
|
+
return True
|
611
610
|
elif scalar_type == scalar_type.DATE:
|
612
|
-
return date.today()
|
611
|
+
return date.today()
|
613
612
|
elif scalar_type == scalar_type.DATETIME:
|
614
|
-
return datetime.now()
|
613
|
+
return datetime.now()
|
615
614
|
elif scalar_type == scalar_type.FLOAT:
|
616
|
-
return
|
615
|
+
return random.random()
|
617
616
|
elif scalar_type == scalar_type.INTEGER:
|
618
|
-
return
|
617
|
+
return random.randint(-1000, 1000)
|
619
618
|
elif scalar_type == scalar_type.JSON:
|
620
619
|
return json.dumps(
|
621
620
|
{_random_string(): [_random_string(), _random_string()], _random_string(): random.random()}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Tuple instead of list so it's hashable and preserves order
|
2
|
-
from typing import Tuple, Union
|
2
|
+
from typing import Any, Dict, List, Tuple, Union
|
3
3
|
|
4
4
|
from benchling_sdk.models import (
|
5
5
|
ArrayElementAppConfigItem,
|
@@ -34,3 +34,5 @@ ConfigurationReference = Union[
|
|
34
34
|
SecureTextAppConfigItem,
|
35
35
|
TextAppConfigItem,
|
36
36
|
]
|
37
|
+
|
38
|
+
JsonType = Union[Dict[str, Any], List[Any], str, int, float, bool]
|
@@ -14,9 +14,8 @@ from benchling_sdk.apps.status.errors import (
|
|
14
14
|
SessionClosedError,
|
15
15
|
SessionContextClosedError,
|
16
16
|
)
|
17
|
-
from benchling_sdk.apps.status.types import _ReferencedSessionLinkType
|
18
17
|
from benchling_sdk.errors import BenchlingError
|
19
|
-
from benchling_sdk.helpers.logging_helpers import
|
18
|
+
from benchling_sdk.helpers.logging_helpers import sdk_logger
|
20
19
|
from benchling_sdk.models import (
|
21
20
|
AppCanvasUpdate,
|
22
21
|
AppSession,
|
@@ -35,8 +34,6 @@ if TYPE_CHECKING:
|
|
35
34
|
|
36
35
|
_DEFAULT_APP_ERROR_MESSAGE = "An unexpected error occurred in the app"
|
37
36
|
|
38
|
-
log_stability_warning(StabilityLevel.BETA)
|
39
|
-
|
40
37
|
|
41
38
|
class SessionProvider(Protocol):
|
42
39
|
"""Provide a Benchling App Session to convey app status."""
|
@@ -685,20 +682,3 @@ def continue_session_context(
|
|
685
682
|
context_enter_handler,
|
686
683
|
context_exit_handler,
|
687
684
|
)
|
688
|
-
|
689
|
-
|
690
|
-
def ref(reference: _ReferencedSessionLinkType) -> str:
|
691
|
-
"""
|
692
|
-
Ref.
|
693
|
-
|
694
|
-
Helper method for easily serializing a referenced object into a string embeddable in AppSessionMessageCreate
|
695
|
-
content.
|
696
|
-
|
697
|
-
Example:
|
698
|
-
dna_sequence = benchling.dna_sequences.get_by_id("seq_1234")
|
699
|
-
AppSessionMessageCreate(f"This is my DNA sequence {ref(dna_sequence)} for analysis"
|
700
|
-
"""
|
701
|
-
# Not sure {} are possible in Benchling IDs, but the spec says we're escaping
|
702
|
-
unescape_id = reference.id
|
703
|
-
escaped_id = unescape_id.replace("{", "\\{").replace("}", "\\}")
|
704
|
-
return f"{{id:{escaped_id}}}"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from benchling_sdk.apps.status.types import ReferencedSessionLinkType
|
4
|
+
|
5
|
+
|
6
|
+
def ref(reference: ReferencedSessionLinkType) -> str:
|
7
|
+
"""
|
8
|
+
Ref.
|
9
|
+
|
10
|
+
Helper method for easily serializing a referenced object into a string embeddable in AppSessionMessageCreate
|
11
|
+
content.
|
12
|
+
|
13
|
+
Example:
|
14
|
+
dna_sequence = benchling.dna_sequences.get_by_id("seq_1234")
|
15
|
+
AppSessionMessageCreate(f"This is my DNA sequence {ref(dna_sequence)} for analysis"
|
16
|
+
"""
|
17
|
+
# Not sure {} are possible in Benchling IDs, but the spec says we're escaping
|
18
|
+
unescape_id = reference.id
|
19
|
+
escaped_id = unescape_id.replace("{", "\\{").replace("}", "\\}")
|
20
|
+
return f"{{id:{escaped_id}}}"
|
@@ -23,7 +23,7 @@ from benchling_sdk.models import (
|
|
23
23
|
|
24
24
|
# Taken from CHIP_SUPPORTED_COLUMN_TYPES in Benchling server
|
25
25
|
# Anything we miss, they can still embed the ID themselves in a message
|
26
|
-
|
26
|
+
ReferencedSessionLinkType = Union[
|
27
27
|
AaSequence,
|
28
28
|
Blob,
|
29
29
|
Box,
|
File without changes
|