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.
Files changed (121) hide show
  1. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/PKG-INFO +2 -2
  2. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/config/decryption_provider.py +0 -3
  3. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/config/framework.py +12 -11
  4. 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
  5. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/config/mock_config.py +68 -69
  6. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/config/types.py +3 -1
  7. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/status/framework.py +1 -21
  8. benchling_sdk-1.10.0a6/benchling_sdk/apps/status/helpers.py +20 -0
  9. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/status/types.py +1 -1
  10. benchling_sdk-1.10.0a6/benchling_sdk/services/v2/stable/__init__.py +0 -0
  11. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/assay_result_service.py +18 -0
  12. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/pyproject.toml +2 -2
  13. benchling_sdk-1.10.0a5/benchling_sdk/apps/config/__init__.py +0 -3
  14. benchling_sdk-1.10.0a5/benchling_sdk/apps/config/scalars.py +0 -190
  15. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/LICENSE +0 -0
  16. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/README.md +0 -0
  17. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/__init__.py +0 -0
  18. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/__init__.py +0 -0
  19. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/canvas/__init__.py +0 -0
  20. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/canvas/errors.py +0 -0
  21. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/canvas/framework.py +0 -0
  22. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/canvas/types.py +0 -0
  23. {benchling_sdk-1.10.0a5/benchling_sdk/apps/helpers → benchling_sdk-1.10.0a6/benchling_sdk/apps/config}/__init__.py +0 -0
  24. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/config/cryptography_helpers.py +0 -0
  25. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/config/errors.py +0 -0
  26. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/framework.py +0 -0
  27. {benchling_sdk-1.10.0a5/benchling_sdk/apps/status → benchling_sdk-1.10.0a6/benchling_sdk/apps/helpers}/__init__.py +0 -0
  28. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/helpers/manifest_helpers.py +0 -0
  29. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/helpers/webhook_helpers.py +0 -0
  30. {benchling_sdk-1.10.0a5/benchling_sdk/helpers → benchling_sdk-1.10.0a6/benchling_sdk/apps/status}/__init__.py +0 -0
  31. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/apps/status/errors.py +0 -0
  32. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/auth/__init__.py +0 -0
  33. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/auth/api_key_auth.py +0 -0
  34. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/auth/bearer_token_auth.py +0 -0
  35. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/auth/client_credentials_oauth2.py +0 -0
  36. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/benchling.py +0 -0
  37. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/docs/__init__.py +0 -0
  38. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/docs/__main__.py +0 -0
  39. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/errors.py +0 -0
  40. {benchling_sdk-1.10.0a5/benchling_sdk/models/webhooks → benchling_sdk-1.10.0a6/benchling_sdk/helpers}/__init__.py +0 -0
  41. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/client_helpers.py +0 -0
  42. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/constants.py +0 -0
  43. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/decorators.py +0 -0
  44. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/file_helpers.py +0 -0
  45. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/logging_helpers.py +0 -0
  46. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/package_helpers.py +0 -0
  47. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/pagination_helpers.py +0 -0
  48. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/response_helpers.py +0 -0
  49. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/retry_helpers.py +0 -0
  50. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/serialization_helpers.py +0 -0
  51. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/helpers/transaction_manager.py +0 -0
  52. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/models/__init__.py +0 -0
  53. {benchling_sdk-1.10.0a5/benchling_sdk/services/v2 → benchling_sdk-1.10.0a6/benchling_sdk/models/webhooks}/__init__.py +0 -0
  54. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/models/webhooks/v0/__init__.py +0 -0
  55. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/py.typed +0 -0
  56. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/__init__.py +0 -0
  57. {benchling_sdk-1.10.0a5/benchling_sdk/services/v2/alpha → benchling_sdk-1.10.0a6/benchling_sdk/services/v2}/__init__.py +0 -0
  58. {benchling_sdk-1.10.0a5/benchling_sdk/services/v2/beta → benchling_sdk-1.10.0a6/benchling_sdk/services/v2/alpha}/__init__.py +0 -0
  59. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/alpha/v2_alpha_app_service.py +0 -0
  60. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/alpha/v2_alpha_dna_sequence_service.py +0 -0
  61. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/base_service.py +0 -0
  62. {benchling_sdk-1.10.0a5/benchling_sdk/services/v2/stable → benchling_sdk-1.10.0a6/benchling_sdk/services/v2/beta}/__init__.py +0 -0
  63. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_aa_sequence_service.py +0 -0
  64. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_app_service.py +0 -0
  65. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_collaboration_service.py +0 -0
  66. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_custom_entity_service.py +0 -0
  67. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_dataset_service.py +0 -0
  68. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_dna_oligo_service.py +0 -0
  69. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_dna_sequence_service.py +0 -0
  70. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_entity_service.py +0 -0
  71. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_entry_service.py +0 -0
  72. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_folder_service.py +0 -0
  73. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_project_service.py +0 -0
  74. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_rna_oligo_service.py +0 -0
  75. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/beta/v2_beta_worklist_service.py +0 -0
  76. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/aa_sequence_service.py +0 -0
  77. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/api_service.py +0 -0
  78. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/app_service.py +0 -0
  79. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/assay_run_service.py +0 -0
  80. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/blob_service.py +0 -0
  81. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/box_service.py +0 -0
  82. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/container_service.py +0 -0
  83. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/custom_entity_service.py +0 -0
  84. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/custom_notation_service.py +0 -0
  85. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/dna_alignments_service.py +0 -0
  86. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/dna_oligo_service.py +0 -0
  87. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/dna_sequence_service.py +0 -0
  88. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/dropdown_service.py +0 -0
  89. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/entry_service.py +0 -0
  90. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/event_service.py +0 -0
  91. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/export_service.py +0 -0
  92. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/feature_library_service.py +0 -0
  93. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/folder_service.py +0 -0
  94. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/inventory_service.py +0 -0
  95. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/lab_automation_service.py +0 -0
  96. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/label_template_service.py +0 -0
  97. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/location_service.py +0 -0
  98. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/mixture_service.py +0 -0
  99. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/molecule_service.py +0 -0
  100. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/nucleotide_alignments_service.py +0 -0
  101. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/oligo_service.py +0 -0
  102. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/organization_service.py +0 -0
  103. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/plate_service.py +0 -0
  104. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/printer_service.py +0 -0
  105. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/project_service.py +0 -0
  106. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/registry_service.py +0 -0
  107. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/request_service.py +0 -0
  108. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/rna_oligo_service.py +0 -0
  109. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/rna_sequence_service.py +0 -0
  110. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/schema_service.py +0 -0
  111. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/task_service.py +0 -0
  112. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/team_service.py +0 -0
  113. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/user_service.py +0 -0
  114. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/warehouse_service.py +0 -0
  115. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/workflow_output_service.py +0 -0
  116. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/workflow_task_group_service.py +0 -0
  117. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/stable/workflow_task_service.py +0 -0
  118. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/v2_alpha_service.py +0 -0
  119. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/v2_beta_service.py +0 -0
  120. {benchling_sdk-1.10.0a5 → benchling_sdk-1.10.0a6}/benchling_sdk/services/v2/v2_stable_service.py +0 -0
  121. {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.0a5
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.232)
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)
@@ -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 + older client could lead to unpredictable results
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 indexable structure.
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
- _configuration_map: Optional[Dict[ConfigItemPath, ConfigItemWrapper]] = None
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 configuration_path_map(self) -> Dict[ConfigItemPath, ConfigItemWrapper]:
256
+ def configuration_path_dict(self) -> Dict[ConfigItemPath, ConfigItemWrapper]:
256
257
  """
257
258
  Config links.
258
259
 
259
- Return a map of configuration item paths to their corresponding configuration items.
260
+ Return a dict of configuration item paths to their corresponding configuration items.
260
261
  """
261
- if not self._configuration_map:
262
- self._configuration_map = {
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._configuration_map
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.configuration_path_map.get(tuple(path), ConfigItemWrapper(None, path))
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 configuration_map to preserve order
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._configuration_map = None
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 date, datetime
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
- from benchling_sdk.apps.config.scalars import JsonType
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 UnsupportedSubTypeError(Exception):
41
+ class _UnsupportedSubTypeError(Exception):
128
42
  """Error when an unsupported subtype is encountered."""
129
43
 
130
44
  pass
131
45
 
132
46
 
133
- def field_definitions_from_dependency(
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 element_definition_from_dependency(dependency: ManifestArrayConfig) -> List[ArrayElementDependency]:
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 enum_from_dependency(
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, ArrayElementDependency]
184
- ) -> ArrayElementDependency:
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 workflow_task_schema_output_from_dependency(
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 options_from_dependency(dependency: DropdownDependency) -> List[BaseManifestConfig]:
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 subtype_from_entity_schema_dependency(
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, Type, Union
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.scalars import (
39
- BoolScalar,
40
- DateScalar,
41
- DateTimeScalar,
42
- FloatScalar,
43
- IntScalar,
44
- JsonScalar,
45
- JsonType,
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.strftime(DateTimeScalar.expected_format()) if isinstance(value, datetime) else 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] = list(),
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 options_from_dependency(dependency)
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 = subtype_from_entity_schema_dependency(dependency)
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 field_definitions_from_dependency(dependency)
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 field_definitions_from_dependency(dependency)
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 field_definitions_from_dependency(dependency)
414
+ for subdependency in _field_definitions_from_dependency(dependency)
422
415
  ]
423
- workflow_task_output = workflow_task_schema_output_from_dependency(dependency)
416
+ workflow_task_output = _workflow_task_schema_output_from_dependency(dependency)
424
417
  if workflow_task_output:
425
- output_fields = field_definitions_from_dependency(workflow_task_output)
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] = list()
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 = _mock_scalar_value_with_conversion(dependency, BoolScalar)
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 = _mock_scalar_value_with_conversion(dependency, DateScalar)
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 = _mock_scalar_value_with_conversion(dependency, DateTimeScalar)
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 = _mock_scalar_value_with_conversion(dependency, FloatScalar)
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 = _mock_scalar_value_with_conversion(dependency, IntScalar)
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 = _mock_scalar_value_with_conversion(dependency, JsonScalar)
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 = _mock_scalar_value_with_conversion(dependency, SecureTextScalar)
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 = _mock_scalar_value_with_conversion(dependency, TextScalar)
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] = list(), rows: int = 1
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 = element_definition_from_dependency(dependency)
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] = list()):
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 _mock_scalar_value_with_conversion(
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
- return str(random.choice(dependency.enum))
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(enum_from_dependency(dependency)) > 0
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] = list(),
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] = list(),
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(scalar_type: ScalarConfigTypes) -> str:
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 scalar_type == scalar_type.BOOLEAN:
610
- return "true"
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().strftime("%Y-%m-%d")
611
+ return date.today()
613
612
  elif scalar_type == scalar_type.DATETIME:
614
- return datetime.now().strftime(DateTimeScalar.expected_format())
613
+ return datetime.now()
615
614
  elif scalar_type == scalar_type.FLOAT:
616
- return str(random.random())
615
+ return random.random()
617
616
  elif scalar_type == scalar_type.INTEGER:
618
- return str(random.randint(-1000, 1000))
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 log_stability_warning, sdk_logger, StabilityLevel
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
- _ReferencedSessionLinkType = Union[
26
+ ReferencedSessionLinkType = Union[
27
27
  AaSequence,
28
28
  Blob,
29
29
  Box,