UncountablePythonSDK 0.0.110__py3-none-any.whl → 0.0.112__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.

Potentially problematic release.


This version of UncountablePythonSDK might be problematic. Click here for more details.

Files changed (136) hide show
  1. docs/conf.py +2 -2
  2. docs/justfile +1 -1
  3. examples/create_ingredient_sdk.py +34 -0
  4. examples/integration-server/jobs/materials_auto/example_runsheet_wh.py +35 -0
  5. examples/integration-server/jobs/materials_auto/profile.yaml +9 -0
  6. examples/integration-server/pyproject.toml +2 -2
  7. pkgs/argument_parser/argument_parser.py +9 -6
  8. pkgs/type_spec/builder.py +19 -2
  9. pkgs/type_spec/emit_python.py +9 -3
  10. pkgs/type_spec/emit_typescript_util.py +16 -1
  11. pkgs/type_spec/parts/base.py.prepart +4 -0
  12. pkgs/type_spec/type_info/emit_type_info.py +12 -3
  13. pkgs/type_spec/ui_entry_actions/__init__.py +4 -0
  14. pkgs/type_spec/ui_entry_actions/generate_ui_entry_actions.py +294 -0
  15. pkgs/type_spec/value_spec/convert_type.py +13 -0
  16. uncountable/core/client.py +7 -4
  17. uncountable/integration/executors/generic_upload_executor.py +3 -2
  18. uncountable/integration/job.py +24 -1
  19. uncountable/integration/queue_runner/datastore/datastore_sqlite.py +3 -2
  20. uncountable/integration/scheduler.py +4 -3
  21. uncountable/types/__init__.py +4 -0
  22. uncountable/types/api/batch/execute_batch.py +4 -4
  23. uncountable/types/api/batch/execute_batch_load_async.py +2 -2
  24. uncountable/types/api/chemical/convert_chemical_formats.py +3 -3
  25. uncountable/types/api/condition_parameters/__init__.py +1 -0
  26. uncountable/types/api/condition_parameters/upsert_condition_match.py +72 -0
  27. uncountable/types/api/entity/create_entities.py +3 -3
  28. uncountable/types/api/entity/create_entity.py +3 -3
  29. uncountable/types/api/entity/create_or_update_entity.py +3 -2
  30. uncountable/types/api/entity/get_entities_data.py +3 -3
  31. uncountable/types/api/entity/grant_entity_permissions.py +3 -2
  32. uncountable/types/api/entity/list_entities.py +4 -4
  33. uncountable/types/api/entity/lock_entity.py +3 -2
  34. uncountable/types/api/entity/lookup_entity.py +5 -5
  35. uncountable/types/api/entity/resolve_entity_ids.py +3 -3
  36. uncountable/types/api/entity/set_entity_field_values.py +3 -2
  37. uncountable/types/api/entity/set_values.py +3 -2
  38. uncountable/types/api/entity/transition_entity_phase.py +5 -4
  39. uncountable/types/api/entity/unlock_entity.py +3 -2
  40. uncountable/types/api/equipment/associate_equipment_input.py +2 -2
  41. uncountable/types/api/field_options/upsert_field_options.py +4 -3
  42. uncountable/types/api/files/download_file.py +4 -3
  43. uncountable/types/api/id_source/list_id_source.py +3 -3
  44. uncountable/types/api/id_source/match_id_source.py +3 -3
  45. uncountable/types/api/input_groups/get_input_group_names.py +3 -3
  46. uncountable/types/api/inputs/create_inputs.py +6 -4
  47. uncountable/types/api/inputs/get_input_data.py +6 -6
  48. uncountable/types/api/inputs/get_input_names.py +3 -3
  49. uncountable/types/api/inputs/get_inputs_data.py +6 -6
  50. uncountable/types/api/inputs/set_input_attribute_values.py +3 -3
  51. uncountable/types/api/inputs/set_input_category.py +3 -2
  52. uncountable/types/api/inputs/set_input_subcategories.py +3 -2
  53. uncountable/types/api/inputs/set_intermediate_type.py +3 -2
  54. uncountable/types/api/material_families/update_entity_material_families.py +2 -2
  55. uncountable/types/api/outputs/get_output_data.py +6 -6
  56. uncountable/types/api/outputs/get_output_names.py +3 -3
  57. uncountable/types/api/outputs/resolve_output_conditions.py +5 -5
  58. uncountable/types/api/permissions/set_core_permissions.py +7 -6
  59. uncountable/types/api/project/get_projects.py +3 -3
  60. uncountable/types/api/project/get_projects_data.py +3 -3
  61. uncountable/types/api/recipe_links/create_recipe_link.py +3 -2
  62. uncountable/types/api/recipe_links/remove_recipe_link.py +3 -2
  63. uncountable/types/api/recipe_metadata/get_recipe_metadata_data.py +3 -3
  64. uncountable/types/api/recipes/add_recipe_to_project.py +3 -2
  65. uncountable/types/api/recipes/add_time_series_data.py +4 -3
  66. uncountable/types/api/recipes/archive_recipes.py +3 -2
  67. uncountable/types/api/recipes/associate_recipe_as_input.py +3 -2
  68. uncountable/types/api/recipes/associate_recipe_as_lot.py +3 -2
  69. uncountable/types/api/recipes/clear_recipe_outputs.py +3 -2
  70. uncountable/types/api/recipes/create_recipe.py +2 -2
  71. uncountable/types/api/recipes/create_recipes.py +4 -4
  72. uncountable/types/api/recipes/disassociate_recipe_as_input.py +3 -2
  73. uncountable/types/api/recipes/edit_recipe_inputs.py +18 -16
  74. uncountable/types/api/recipes/get_column_calculation_values.py +3 -3
  75. uncountable/types/api/recipes/get_curve.py +2 -2
  76. uncountable/types/api/recipes/get_recipe_calculations.py +3 -3
  77. uncountable/types/api/recipes/get_recipe_links.py +2 -2
  78. uncountable/types/api/recipes/get_recipe_names.py +3 -3
  79. uncountable/types/api/recipes/get_recipe_output_metadata.py +3 -3
  80. uncountable/types/api/recipes/get_recipes_data.py +11 -11
  81. uncountable/types/api/recipes/lock_recipes.py +4 -3
  82. uncountable/types/api/recipes/remove_recipe_from_project.py +3 -2
  83. uncountable/types/api/recipes/set_recipe_inputs.py +3 -3
  84. uncountable/types/api/recipes/set_recipe_metadata.py +3 -2
  85. uncountable/types/api/recipes/set_recipe_output_annotations.py +6 -6
  86. uncountable/types/api/recipes/set_recipe_output_file.py +3 -3
  87. uncountable/types/api/recipes/set_recipe_outputs.py +4 -4
  88. uncountable/types/api/recipes/set_recipe_tags.py +6 -6
  89. uncountable/types/api/recipes/unarchive_recipes.py +3 -2
  90. uncountable/types/api/recipes/unlock_recipes.py +3 -2
  91. uncountable/types/api/runsheet/__init__.py +1 -0
  92. uncountable/types/api/runsheet/complete_async_upload.py +41 -0
  93. uncountable/types/api/triggers/run_trigger.py +3 -2
  94. uncountable/types/api/uploader/invoke_uploader.py +2 -2
  95. uncountable/types/async_batch_processor.py +74 -0
  96. uncountable/types/async_batch_t.py +7 -5
  97. uncountable/types/auth_retrieval_t.py +4 -3
  98. uncountable/types/base_t.py +4 -0
  99. uncountable/types/calculations_t.py +1 -1
  100. uncountable/types/chemical_structure_t.py +2 -1
  101. uncountable/types/client_base.py +48 -0
  102. uncountable/types/client_config_t.py +2 -1
  103. uncountable/types/curves_t.py +2 -2
  104. uncountable/types/data_t.py +22 -21
  105. uncountable/types/entity_t.py +9 -3
  106. uncountable/types/experiment_groups_t.py +1 -1
  107. uncountable/types/field_values_t.py +20 -20
  108. uncountable/types/fields_t.py +1 -1
  109. uncountable/types/generic_upload_t.py +7 -6
  110. uncountable/types/id_source_t.py +5 -4
  111. uncountable/types/identifier_t.py +3 -3
  112. uncountable/types/input_attributes_t.py +1 -1
  113. uncountable/types/inputs_t.py +1 -1
  114. uncountable/types/integration_server_t.py +2 -1
  115. uncountable/types/job_definition_t.py +14 -13
  116. uncountable/types/outputs_t.py +1 -1
  117. uncountable/types/overrides_t.py +3 -2
  118. uncountable/types/phases_t.py +1 -1
  119. uncountable/types/queued_job_t.py +7 -7
  120. uncountable/types/recipe_identifiers_t.py +3 -3
  121. uncountable/types/recipe_links_t.py +1 -1
  122. uncountable/types/recipe_metadata_t.py +3 -3
  123. uncountable/types/recipe_output_metadata_t.py +1 -1
  124. uncountable/types/recipe_tags_t.py +1 -1
  125. uncountable/types/recipe_workflow_steps_t.py +5 -4
  126. uncountable/types/recipes_t.py +2 -1
  127. uncountable/types/response_t.py +2 -1
  128. uncountable/types/secret_retrieval_t.py +4 -3
  129. uncountable/types/units_t.py +1 -1
  130. uncountable/types/users_t.py +1 -1
  131. uncountable/types/webhook_job_t.py +4 -3
  132. uncountable/types/workflows_t.py +2 -2
  133. {uncountablepythonsdk-0.0.110.dist-info → uncountablepythonsdk-0.0.112.dist-info}/METADATA +2 -1
  134. {uncountablepythonsdk-0.0.110.dist-info → uncountablepythonsdk-0.0.112.dist-info}/RECORD +136 -128
  135. {uncountablepythonsdk-0.0.110.dist-info → uncountablepythonsdk-0.0.112.dist-info}/WHEEL +1 -1
  136. {uncountablepythonsdk-0.0.110.dist-info → uncountablepythonsdk-0.0.112.dist-info}/top_level.txt +0 -0
@@ -13,6 +13,7 @@ import uncountable.types.api.recipes.associate_recipe_as_lot as associate_recipe
13
13
  from uncountable.types import async_batch_t
14
14
  from uncountable.types import base_t
15
15
  import uncountable.types.api.recipes.clear_recipe_outputs as clear_recipe_outputs_t
16
+ import uncountable.types.api.runsheet.complete_async_upload as complete_async_upload_t
16
17
  import uncountable.types.api.entity.create_or_update_entity as create_or_update_entity_t
17
18
  import uncountable.types.api.recipes.create_recipe as create_recipe_t
18
19
  import uncountable.types.api.recipes.edit_recipe_inputs as edit_recipe_inputs_t
@@ -28,6 +29,7 @@ from uncountable.types import recipe_metadata_t
28
29
  from uncountable.types import recipe_workflow_steps_t
29
30
  import uncountable.types.api.entity.set_entity_field_values as set_entity_field_values_t
30
31
  import uncountable.types.api.recipes.set_recipe_metadata as set_recipe_metadata_t
32
+ import uncountable.types.api.condition_parameters.upsert_condition_match as upsert_condition_match_t
31
33
  import uuid
32
34
  from abc import ABC, abstractmethod
33
35
  from pkgs.serialization_util import serialize_for_api
@@ -182,6 +184,39 @@ class AsyncBatchProcessorBase(ABC):
182
184
  batch_reference=req.batch_reference,
183
185
  )
184
186
 
187
+ def complete_async_upload(
188
+ self,
189
+ *,
190
+ async_job_id: base_t.ObjectId,
191
+ file_id: base_t.ObjectId,
192
+ depends_on: list[str] | None = None,
193
+ ) -> async_batch_t.QueuedAsyncBatchRequest:
194
+ """Processes an file id with a given async job id to be uploaded asynchronously
195
+
196
+ :param depends_on: A list of batch reference keys to process before processing this request
197
+ """
198
+ args = complete_async_upload_t.Arguments(
199
+ async_job_id=async_job_id,
200
+ file_id=file_id,
201
+ )
202
+ json_data = serialize_for_api(args)
203
+
204
+ batch_reference = str(uuid.uuid4())
205
+
206
+ req = async_batch_t.AsyncBatchRequest(
207
+ path=async_batch_t.AsyncBatchRequestPath.COMPLETE_ASYNC_UPLOAD,
208
+ data=json_data,
209
+ depends_on=depends_on,
210
+ batch_reference=batch_reference,
211
+ )
212
+
213
+ self._enqueue(req)
214
+
215
+ return async_batch_t.QueuedAsyncBatchRequest(
216
+ path=req.path,
217
+ batch_reference=req.batch_reference,
218
+ )
219
+
185
220
  def create_or_update_entity(
186
221
  self,
187
222
  *,
@@ -489,3 +524,42 @@ class AsyncBatchProcessorBase(ABC):
489
524
  path=req.path,
490
525
  batch_reference=req.batch_reference,
491
526
  )
527
+
528
+ def upsert_condition_match(
529
+ self,
530
+ *,
531
+ explicit_name: bool = False,
532
+ name: str | None = None,
533
+ condition_parameters: list[upsert_condition_match_t.ConditionParameter] | None = None,
534
+ output_conditions: list[identifier_t.IdentifierKey] | None = None,
535
+ existing_condition_match: identifier_t.IdentifierKey | None = None,
536
+ depends_on: list[str] | None = None,
537
+ ) -> async_batch_t.QueuedAsyncBatchRequest:
538
+ """Creates or updates condition match
539
+
540
+ :param depends_on: A list of batch reference keys to process before processing this request
541
+ """
542
+ args = upsert_condition_match_t.Arguments(
543
+ name=name,
544
+ condition_parameters=condition_parameters,
545
+ output_conditions=output_conditions,
546
+ explicit_name=explicit_name,
547
+ existing_condition_match=existing_condition_match,
548
+ )
549
+ json_data = serialize_for_api(args)
550
+
551
+ batch_reference = str(uuid.uuid4())
552
+
553
+ req = async_batch_t.AsyncBatchRequest(
554
+ path=async_batch_t.AsyncBatchRequestPath.UPSERT_CONDITION_MATCH,
555
+ data=json_data,
556
+ depends_on=depends_on,
557
+ batch_reference=batch_reference,
558
+ )
559
+
560
+ self._enqueue(req)
561
+
562
+ return async_batch_t.QueuedAsyncBatchRequest(
563
+ path=req.path,
564
+ batch_reference=req.batch_reference,
565
+ )
@@ -42,6 +42,8 @@ class AsyncBatchRequestPath(StrEnum):
42
42
  ADD_TIME_SERIES_DATA = "recipes/add_time_series_data"
43
43
  LOOKUP_ENTITY = "entity/lookup_entity"
44
44
  CREATE_RECIPE_LINK = "recipe_links/create_recipe_link"
45
+ UPSERT_CONDITION_MATCH = "condition_parameters/upsert_condition_match"
46
+ COMPLETE_ASYNC_UPLOAD = "runsheet/complete_async_upload"
45
47
 
46
48
 
47
49
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -49,7 +51,7 @@ class AsyncBatchRequestPath(StrEnum):
49
51
  named_type_path="sdk.async_batch.AsyncBatchRequest",
50
52
  unconverted_values={"data"},
51
53
  )
52
- @dataclasses.dataclass(kw_only=True)
54
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
53
55
  class AsyncBatchRequest:
54
56
  path: AsyncBatchRequestPath
55
57
  data: base_t.JsonValue
@@ -62,7 +64,7 @@ class AsyncBatchRequest:
62
64
  named_type_path="sdk.async_batch.AsyncBatchResultValue",
63
65
  unconverted_values={"value"},
64
66
  )
65
- @dataclasses.dataclass(kw_only=True)
67
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
66
68
  class AsyncBatchResultValue:
67
69
  data_key: str
68
70
  value: base_t.JsonValue
@@ -72,7 +74,7 @@ class AsyncBatchResultValue:
72
74
  @serial_class(
73
75
  named_type_path="sdk.async_batch.AsyncBatchActionReturn",
74
76
  )
75
- @dataclasses.dataclass(kw_only=True)
77
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
76
78
  class AsyncBatchActionReturn:
77
79
  modification_made: bool
78
80
  result_id: base_t.ObjectId | None = None
@@ -84,7 +86,7 @@ class AsyncBatchActionReturn:
84
86
  @serial_class(
85
87
  named_type_path="sdk.async_batch.SavedAsyncBatchActionReturn",
86
88
  )
87
- @dataclasses.dataclass(kw_only=True)
89
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
88
90
  class SavedAsyncBatchActionReturn:
89
91
  identifier: str
90
92
  result_data: AsyncBatchActionReturn
@@ -94,7 +96,7 @@ class SavedAsyncBatchActionReturn:
94
96
  @serial_class(
95
97
  named_type_path="sdk.async_batch.QueuedAsyncBatchRequest",
96
98
  )
97
- @dataclasses.dataclass(kw_only=True, frozen=True, eq=True)
99
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True, frozen=True, eq=True) # type: ignore[literal-required]
98
100
  class QueuedAsyncBatchRequest:
99
101
  path: AsyncBatchRequestPath
100
102
  batch_reference: str
@@ -10,6 +10,7 @@ from enum import StrEnum
10
10
  import dataclasses
11
11
  from pkgs.serialization import serial_class
12
12
  from pkgs.serialization import serial_union_annotation
13
+ from . import base_t
13
14
  from . import secret_retrieval_t
14
15
 
15
16
  __all__: list[str] = [
@@ -31,7 +32,7 @@ class AuthRetrievalType(StrEnum):
31
32
  @serial_class(
32
33
  named_type_path="sdk.auth_retrieval.AuthRetrievalBase",
33
34
  )
34
- @dataclasses.dataclass(kw_only=True)
35
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
35
36
  class AuthRetrievalBase:
36
37
  type: AuthRetrievalType
37
38
 
@@ -41,7 +42,7 @@ class AuthRetrievalBase:
41
42
  named_type_path="sdk.auth_retrieval.AuthRetrievalOAuth",
42
43
  parse_require={"type"},
43
44
  )
44
- @dataclasses.dataclass(kw_only=True)
45
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
45
46
  class AuthRetrievalOAuth(AuthRetrievalBase):
46
47
  type: typing.Literal[AuthRetrievalType.OAUTH] = AuthRetrievalType.OAUTH
47
48
  refresh_token_secret: secret_retrieval_t.SecretRetrieval
@@ -52,7 +53,7 @@ class AuthRetrievalOAuth(AuthRetrievalBase):
52
53
  named_type_path="sdk.auth_retrieval.AuthRetrievalBasic",
53
54
  parse_require={"type"},
54
55
  )
55
- @dataclasses.dataclass(kw_only=True)
56
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
56
57
  class AuthRetrievalBasic(AuthRetrievalBase):
57
58
  type: typing.Literal[AuthRetrievalType.BASIC] = AuthRetrievalType.BASIC
58
59
  api_id_secret: secret_retrieval_t.SecretRetrieval
@@ -44,6 +44,10 @@ REF_NAME_STRICT_REGEX = rf"{REF_NAME_STRICT_REGEX_STRING}"
44
44
  ID_REGEX = r"-?[1-9][0-9]{0,20}"
45
45
 
46
46
 
47
+ # ENABLE_SLOTS should be removed after slots have been tested locally
48
+ import os
49
+ ENABLE_SLOTS = os.environ.get("UNC_ENABLE_DATACLASS_SLOTS") == "true"
50
+
47
51
  if TYPE_CHECKING:
48
52
  JsonValue = Union[JsonScalar, Mapping[str, "JsonValue"], Sequence["JsonValue"]]
49
53
  ExtJsonValue = JsonValue
@@ -19,7 +19,7 @@ __all__: list[str] = [
19
19
  @serial_class(
20
20
  named_type_path="sdk.calculations.Calculation",
21
21
  )
22
- @dataclasses.dataclass(kw_only=True)
22
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
23
23
  class Calculation:
24
24
  id: base_t.ObjectId
25
25
  name: str
@@ -8,6 +8,7 @@ import datetime # noqa: F401
8
8
  from decimal import Decimal # noqa: F401
9
9
  import dataclasses
10
10
  from pkgs.serialization import serial_class
11
+ from . import base_t
11
12
 
12
13
  __all__: list[str] = [
13
14
  "ChemicalStructure",
@@ -19,7 +20,7 @@ __all__: list[str] = [
19
20
  named_type_path="sdk.chemical_structure.ChemicalStructure",
20
21
  to_string_values={"molecular_weight"},
21
22
  )
22
- @dataclasses.dataclass(kw_only=True)
23
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
23
24
  class ChemicalStructure:
24
25
  ketcher_file: str | None = None
25
26
  gross_formula: str | None = None
@@ -17,6 +17,7 @@ import uncountable.types.api.recipes.associate_recipe_as_lot as associate_recipe
17
17
  from uncountable.types import async_batch_t
18
18
  from uncountable.types import base_t
19
19
  import uncountable.types.api.recipes.clear_recipe_outputs as clear_recipe_outputs_t
20
+ import uncountable.types.api.runsheet.complete_async_upload as complete_async_upload_t
20
21
  import uncountable.types.api.chemical.convert_chemical_formats as convert_chemical_formats_t
21
22
  import uncountable.types.api.entity.create_entities as create_entities_t
22
23
  import uncountable.types.api.entity.create_entity as create_entity_t
@@ -88,6 +89,7 @@ import uncountable.types.api.recipes.unarchive_recipes as unarchive_recipes_t
88
89
  import uncountable.types.api.entity.unlock_entity as unlock_entity_t
89
90
  import uncountable.types.api.recipes.unlock_recipes as unlock_recipes_t
90
91
  import uncountable.types.api.material_families.update_entity_material_families as update_entity_material_families_t
92
+ import uncountable.types.api.condition_parameters.upsert_condition_match as upsert_condition_match_t
91
93
  import uncountable.types.api.field_options.upsert_field_options as upsert_field_options_t
92
94
  from abc import ABC, abstractmethod
93
95
  import dataclasses
@@ -265,6 +267,26 @@ class ClientMethods(ABC):
265
267
  )
266
268
  return self.do_request(api_request=api_request, return_type=clear_recipe_outputs_t.Data)
267
269
 
270
+ def complete_async_upload(
271
+ self,
272
+ *,
273
+ async_job_id: base_t.ObjectId,
274
+ file_id: base_t.ObjectId,
275
+ ) -> complete_async_upload_t.Data:
276
+ """Processes an file id with a given async job id to be uploaded asynchronously
277
+
278
+ """
279
+ args = complete_async_upload_t.Arguments(
280
+ async_job_id=async_job_id,
281
+ file_id=file_id,
282
+ )
283
+ api_request = APIRequest(
284
+ method=complete_async_upload_t.ENDPOINT_METHOD,
285
+ endpoint=complete_async_upload_t.ENDPOINT_PATH,
286
+ args=args,
287
+ )
288
+ return self.do_request(api_request=api_request, return_type=complete_async_upload_t.Data)
289
+
268
290
  def convert_chemical_formats(
269
291
  self,
270
292
  *,
@@ -1673,6 +1695,32 @@ class ClientMethods(ABC):
1673
1695
  )
1674
1696
  return self.do_request(api_request=api_request, return_type=update_entity_material_families_t.Data)
1675
1697
 
1698
+ def upsert_condition_match(
1699
+ self,
1700
+ *,
1701
+ explicit_name: bool = False,
1702
+ name: str | None = None,
1703
+ condition_parameters: list[upsert_condition_match_t.ConditionParameter] | None = None,
1704
+ output_conditions: list[identifier_t.IdentifierKey] | None = None,
1705
+ existing_condition_match: identifier_t.IdentifierKey | None = None,
1706
+ ) -> upsert_condition_match_t.Data:
1707
+ """Creates or updates condition match
1708
+
1709
+ """
1710
+ args = upsert_condition_match_t.Arguments(
1711
+ name=name,
1712
+ condition_parameters=condition_parameters,
1713
+ output_conditions=output_conditions,
1714
+ explicit_name=explicit_name,
1715
+ existing_condition_match=existing_condition_match,
1716
+ )
1717
+ api_request = APIRequest(
1718
+ method=upsert_condition_match_t.ENDPOINT_METHOD,
1719
+ endpoint=upsert_condition_match_t.ENDPOINT_PATH,
1720
+ args=args,
1721
+ )
1722
+ return self.do_request(api_request=api_request, return_type=upsert_condition_match_t.Data)
1723
+
1676
1724
  def upsert_field_options(
1677
1725
  self,
1678
1726
  *,
@@ -8,6 +8,7 @@ import datetime # noqa: F401
8
8
  from decimal import Decimal # noqa: F401
9
9
  import dataclasses
10
10
  from pkgs.serialization import serial_class
11
+ from . import base_t
11
12
 
12
13
  __all__: list[str] = [
13
14
  "ClientConfigOptions",
@@ -18,7 +19,7 @@ __all__: list[str] = [
18
19
  @serial_class(
19
20
  named_type_path="sdk.client_config.ClientConfigOptions",
20
21
  )
21
- @dataclasses.dataclass(kw_only=True)
22
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
22
23
  class ClientConfigOptions:
23
24
  allow_insecure_tls: bool = False
24
25
  extra_headers: dict[str, str] | None = None
@@ -28,7 +28,7 @@ class CurveAxisType(StrEnum):
28
28
  @serial_class(
29
29
  named_type_path="sdk.curves.Curve",
30
30
  )
31
- @dataclasses.dataclass(kw_only=True)
31
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
32
32
  class Curve:
33
33
  id: base_t.ObjectId
34
34
  x_type: typing.Literal[CurveAxisType.NUMERIC] | typing.Literal[CurveAxisType.TIMESTAMP]
@@ -42,7 +42,7 @@ class Curve:
42
42
  named_type_path="sdk.curves.CurveValue",
43
43
  to_string_values={"quantity"},
44
44
  )
45
- @dataclasses.dataclass(kw_only=True)
45
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
46
46
  class CurveValue:
47
47
  index: int
48
48
  quantity: Decimal | None = None
@@ -8,6 +8,7 @@ import datetime # noqa: F401
8
8
  from decimal import Decimal # noqa: F401
9
9
  import dataclasses
10
10
  from pkgs.serialization import serial_class
11
+ from . import base_t
11
12
 
12
13
  __all__: list[str] = [
13
14
  "CielabColor",
@@ -24,11 +25,11 @@ __all__: list[str] = [
24
25
  named_type_path="sdk.data.RgbColor",
25
26
  unconverted_keys={"B", "G", "R"},
26
27
  )
27
- @dataclasses.dataclass(kw_only=True)
28
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
28
29
  class RgbColor:
29
- R: int
30
- G: int
31
- B: int
30
+ R: Decimal
31
+ G: Decimal
32
+ B: Decimal
32
33
 
33
34
 
34
35
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -36,11 +37,11 @@ class RgbColor:
36
37
  named_type_path="sdk.data.CielabColor",
37
38
  unconverted_keys={"L", "a", "b"},
38
39
  )
39
- @dataclasses.dataclass(kw_only=True)
40
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
40
41
  class CielabColor:
41
- L: int
42
- a: int
43
- b: int
42
+ L: Decimal
43
+ a: Decimal
44
+ b: Decimal
44
45
 
45
46
 
46
47
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -48,11 +49,11 @@ class CielabColor:
48
49
  named_type_path="sdk.data.XyzColor",
49
50
  unconverted_keys={"X", "Y", "Z"},
50
51
  )
51
- @dataclasses.dataclass(kw_only=True)
52
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
52
53
  class XyzColor:
53
- X: int
54
- Y: int
55
- Z: int
54
+ X: Decimal
55
+ Y: Decimal
56
+ Z: Decimal
56
57
 
57
58
 
58
59
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -60,11 +61,11 @@ class XyzColor:
60
61
  named_type_path="sdk.data.LChColor",
61
62
  unconverted_keys={"C", "L", "h"},
62
63
  )
63
- @dataclasses.dataclass(kw_only=True)
64
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
64
65
  class LChColor:
65
- L: int
66
- C: int
67
- h: int
66
+ L: Decimal
67
+ C: Decimal
68
+ h: Decimal
68
69
 
69
70
 
70
71
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -72,11 +73,11 @@ class LChColor:
72
73
  named_type_path="sdk.data.HslColor",
73
74
  unconverted_keys={"L", "h", "s"},
74
75
  )
75
- @dataclasses.dataclass(kw_only=True)
76
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
76
77
  class HslColor:
77
- h: int
78
- s: int
79
- L: int
78
+ h: Decimal
79
+ s: Decimal
80
+ L: Decimal
80
81
 
81
82
 
82
83
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -84,7 +85,7 @@ class HslColor:
84
85
  named_type_path="sdk.data.RecipeOutputColor",
85
86
  unconverted_keys={"CIELAB", "LCH", "RGB", "XYZ"},
86
87
  )
87
- @dataclasses.dataclass(kw_only=True)
88
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
88
89
  class RecipeOutputColor:
89
90
  RGB: RgbColor
90
91
  CIELAB: CielabColor
@@ -39,8 +39,10 @@ __all__: list[str] = [
39
39
  "characterization": "Characterization",
40
40
  "comment": "Comment",
41
41
  "comment_thread": "Comment Thread",
42
+ "condition_match": "Condition Match",
42
43
  "condition_parameter": "Condition Parameter",
43
44
  "condition_parameter_mat_family": "Condition Parameter Material Family",
45
+ "condition_parameter_rule": "Condition Parameter Rule",
44
46
  "condition_parameter_value": "Condition Parameter Value",
45
47
  "constraint": "Constraint",
46
48
  "constraint_set": "Constraint Set",
@@ -113,6 +115,7 @@ __all__: list[str] = [
113
115
  "output_condition_parameter_analytical_method_category": "Output Condition Parameter Analytical Method Category",
114
116
  "output_condition_parameter_analytical_method": "Output Condition Parameter Analytical Method",
115
117
  "output_group": "Output Group",
118
+ "output_group_member": "Output Group Member",
116
119
  "output_preferences": "Output Preferences",
117
120
  "permission": "Permission",
118
121
  "permissions_recipe_link_inheritance": "Permissions Recipe Link Inheritance",
@@ -217,8 +220,10 @@ class EntityType(StrEnum):
217
220
  CHARACTERIZATION = "characterization"
218
221
  COMMENT = "comment"
219
222
  COMMENT_THREAD = "comment_thread"
223
+ CONDITION_MATCH = "condition_match"
220
224
  CONDITION_PARAMETER = "condition_parameter"
221
225
  CONDITION_PARAMETER_MAT_FAMILY = "condition_parameter_mat_family"
226
+ CONDITION_PARAMETER_RULE = "condition_parameter_rule"
222
227
  CONDITION_PARAMETER_VALUE = "condition_parameter_value"
223
228
  CONSTRAINT = "constraint"
224
229
  CONSTRAINT_SET = "constraint_set"
@@ -291,6 +296,7 @@ class EntityType(StrEnum):
291
296
  OUTPUT_CONDITION_PARAMETER_ANALYTICAL_METHOD_CATEGORY = "output_condition_parameter_analytical_method_category"
292
297
  OUTPUT_CONDITION_PARAMETER_ANALYTICAL_METHOD = "output_condition_parameter_analytical_method"
293
298
  OUTPUT_GROUP = "output_group"
299
+ OUTPUT_GROUP_MEMBER = "output_group_member"
294
300
  OUTPUT_PREFERENCES = "output_preferences"
295
301
  PERMISSION = "permission"
296
302
  PERMISSIONS_RECIPE_LINK_INHERITANCE = "permissions_recipe_link_inheritance"
@@ -384,7 +390,7 @@ class EntityType(StrEnum):
384
390
 
385
391
  # DO NOT MODIFY -- This file is generated by type_spec
386
392
  LimitedEntityType = typing.Annotated[
387
- typing.Literal[EntityType.LAB_REQUEST] | typing.Literal[EntityType.APPROVAL] | typing.Literal[EntityType.CUSTOM_ENTITY] | typing.Literal[EntityType.INGREDIENT_ATTRIBUTE] | typing.Literal[EntityType.INVENTORY_AMOUNT] | typing.Literal[EntityType.TASK] | typing.Literal[EntityType.PROJECT] | typing.Literal[EntityType.EQUIPMENT] | typing.Literal[EntityType.INV_LOCAL_LOCATIONS] | typing.Literal[EntityType.FIELD_OPTION_SET] | typing.Literal[EntityType.WEBHOOK] | typing.Literal[EntityType.SPECS] | typing.Literal[EntityType.GOAL] | typing.Literal[EntityType.INGREDIENT_TAG_MAP] | typing.Literal[EntityType.INGREDIENT_TAG] | typing.Literal[EntityType.CONDITION_PARAMETER] | typing.Literal[EntityType.OUTPUT] | typing.Literal[EntityType.OUTPUT_CONDITION_PARAMETER] | typing.Literal[EntityType.ASYNC_JOB] | typing.Literal[EntityType.CONSTRAINT] | typing.Literal[EntityType.INGREDIENT_CATEGORY_ALL] | typing.Literal[EntityType.TIME_SERIES_SEGMENT] | typing.Literal[EntityType.EQUIPMENT_MAINTENANCE] | typing.Literal[EntityType.MAINTENANCE_SCHEDULE],
393
+ typing.Literal[EntityType.LAB_REQUEST] | typing.Literal[EntityType.APPROVAL] | typing.Literal[EntityType.CUSTOM_ENTITY] | typing.Literal[EntityType.INGREDIENT_ATTRIBUTE] | typing.Literal[EntityType.INVENTORY_AMOUNT] | typing.Literal[EntityType.TASK] | typing.Literal[EntityType.PROJECT] | typing.Literal[EntityType.EQUIPMENT] | typing.Literal[EntityType.INV_LOCAL_LOCATIONS] | typing.Literal[EntityType.FIELD_OPTION_SET] | typing.Literal[EntityType.WEBHOOK] | typing.Literal[EntityType.SPECS] | typing.Literal[EntityType.GOAL] | typing.Literal[EntityType.INGREDIENT_TAG_MAP] | typing.Literal[EntityType.INGREDIENT_TAG] | typing.Literal[EntityType.CONDITION_PARAMETER] | typing.Literal[EntityType.OUTPUT] | typing.Literal[EntityType.OUTPUT_CONDITION_PARAMETER] | typing.Literal[EntityType.ASYNC_JOB] | typing.Literal[EntityType.CONSTRAINT] | typing.Literal[EntityType.INGREDIENT_CATEGORY_ALL] | typing.Literal[EntityType.TIME_SERIES_SEGMENT] | typing.Literal[EntityType.EQUIPMENT_MAINTENANCE] | typing.Literal[EntityType.MAINTENANCE_SCHEDULE] | typing.Literal[EntityType.CONDITION_PARAMETER_RULE] | typing.Literal[EntityType.INGREDIENT],
388
394
  serial_alias_annotation(
389
395
  named_type_path="sdk.entity.LimitedEntityType",
390
396
  ),
@@ -413,7 +419,7 @@ GrantableEntityPermissionType = typing.Annotated[
413
419
  @serial_class(
414
420
  named_type_path="sdk.entity.Entity",
415
421
  )
416
- @dataclasses.dataclass(kw_only=True)
422
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
417
423
  class Entity:
418
424
  id: base_t.ObjectId
419
425
  type: EntityType
@@ -423,7 +429,7 @@ class Entity:
423
429
  @serial_class(
424
430
  named_type_path="sdk.entity.EntityIdentifier",
425
431
  )
426
- @dataclasses.dataclass(kw_only=True, frozen=True, eq=True)
432
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True, frozen=True, eq=True) # type: ignore[literal-required]
427
433
  class EntityIdentifier:
428
434
  identifier_key: identifier_t.IdentifierKey
429
435
  type: EntityType
@@ -19,7 +19,7 @@ __all__: list[str] = [
19
19
  @serial_class(
20
20
  named_type_path="sdk.experiment_groups.SimpleExperimentGroup",
21
21
  )
22
- @dataclasses.dataclass(kw_only=True)
22
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
23
23
  class SimpleExperimentGroup:
24
24
  experiment_group_id: base_t.ObjectId
25
25
  name: str