UncountablePythonSDK 0.0.20__py3-none-any.whl → 0.0.22__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 (55) hide show
  1. {UncountablePythonSDK-0.0.20.dist-info → UncountablePythonSDK-0.0.22.dist-info}/METADATA +3 -1
  2. {UncountablePythonSDK-0.0.20.dist-info → UncountablePythonSDK-0.0.22.dist-info}/RECORD +55 -34
  3. examples/async_batch.py +36 -0
  4. examples/upload_files.py +19 -0
  5. pkgs/type_spec/actions_registry/__main__.py +35 -23
  6. pkgs/type_spec/actions_registry/emit_typescript.py +71 -9
  7. pkgs/type_spec/builder.py +125 -8
  8. pkgs/type_spec/config.py +1 -0
  9. pkgs/type_spec/emit_open_api.py +197 -16
  10. pkgs/type_spec/emit_open_api_util.py +18 -0
  11. pkgs/type_spec/emit_python.py +241 -55
  12. pkgs/type_spec/load_types.py +48 -5
  13. pkgs/type_spec/open_api_util.py +13 -33
  14. pkgs/type_spec/type_info/emit_type_info.py +129 -8
  15. type_spec/external/api/entity/create_entities.yaml +13 -1
  16. type_spec/external/api/entity/create_entity.yaml +13 -1
  17. type_spec/external/api/entity/transition_entity_phase.yaml +44 -0
  18. type_spec/external/api/permissions/set_core_permissions.yaml +69 -0
  19. type_spec/external/api/recipes/associate_recipe_as_input.yaml +4 -4
  20. type_spec/external/api/recipes/create_recipe.yaml +2 -1
  21. type_spec/external/api/recipes/disassociate_recipe_as_input.yaml +16 -0
  22. type_spec/external/api/recipes/edit_recipe_inputs.yaml +86 -0
  23. type_spec/external/api/recipes/get_curve.yaml +4 -1
  24. type_spec/external/api/recipes/get_recipes_data.yaml +6 -0
  25. type_spec/external/api/recipes/set_recipe_metadata.yaml +1 -0
  26. type_spec/external/api/recipes/set_recipe_tags.yaml +62 -0
  27. uncountable/core/__init__.py +3 -1
  28. uncountable/core/async_batch.py +22 -0
  29. uncountable/core/client.py +84 -10
  30. uncountable/core/file_upload.py +95 -0
  31. uncountable/core/types.py +22 -0
  32. uncountable/types/__init__.py +18 -0
  33. uncountable/types/api/entity/create_entities.py +1 -1
  34. uncountable/types/api/entity/create_entity.py +1 -1
  35. uncountable/types/api/entity/transition_entity_phase.py +66 -0
  36. uncountable/types/api/permissions/__init__.py +1 -0
  37. uncountable/types/api/permissions/set_core_permissions.py +89 -0
  38. uncountable/types/api/recipes/associate_recipe_as_input.py +4 -3
  39. uncountable/types/api/recipes/create_recipe.py +1 -1
  40. uncountable/types/api/recipes/disassociate_recipe_as_input.py +35 -0
  41. uncountable/types/api/recipes/edit_recipe_inputs.py +106 -0
  42. uncountable/types/api/recipes/get_curve.py +2 -1
  43. uncountable/types/api/recipes/get_recipes_data.py +2 -0
  44. uncountable/types/api/recipes/set_recipe_tags.py +91 -0
  45. uncountable/types/async_batch.py +10 -0
  46. uncountable/types/async_batch_processor.py +154 -0
  47. uncountable/types/client_base.py +113 -48
  48. uncountable/types/identifier.py +3 -3
  49. uncountable/types/permissions.py +46 -0
  50. uncountable/types/post_base.py +30 -0
  51. uncountable/types/recipe_inputs.py +30 -0
  52. uncountable/types/recipe_metadata.py +2 -0
  53. uncountable/types/recipe_workflow_steps.py +77 -0
  54. {UncountablePythonSDK-0.0.20.dist-info → UncountablePythonSDK-0.0.22.dist-info}/WHEEL +0 -0
  55. {UncountablePythonSDK-0.0.20.dist-info → UncountablePythonSDK-0.0.22.dist-info}/top_level.txt +0 -0
@@ -11,8 +11,8 @@ from decimal import Decimal # noqa: F401
11
11
  from pkgs.serialization import OpaqueKey
12
12
  import uncountable.types.api.recipes.associate_recipe_as_input as associate_recipe_as_input_t
13
13
  import uncountable.types.api.recipes.associate_recipe_as_lot as associate_recipe_as_lot_t
14
- from . import async_batch as async_batch_t
15
- from . import base as base_t
14
+ from uncountable.types import async_batch as async_batch_t
15
+ from uncountable.types import base as base_t
16
16
  import uncountable.types.api.chemical.convert_chemical_formats as convert_chemical_formats_t
17
17
  import uncountable.types.api.entity.create_entities as create_entities_t
18
18
  import uncountable.types.api.entity.create_entity as create_entity_t
@@ -20,10 +20,11 @@ import uncountable.types.api.inputs.create_inputs as create_inputs_t
20
20
  import uncountable.types.api.recipes.create_recipe as create_recipe_t
21
21
  import uncountable.types.api.recipe_links.create_recipe_link as create_recipe_link_t
22
22
  import uncountable.types.api.recipes.create_recipes as create_recipes_t
23
- from . import entity as entity_t
23
+ import uncountable.types.api.recipes.disassociate_recipe_as_input as disassociate_recipe_as_input_t
24
+ from uncountable.types import entity as entity_t
24
25
  import uncountable.types.api.batch.execute_batch as execute_batch_t
25
26
  import uncountable.types.api.batch.execute_batch_load_async as execute_batch_load_async_t
26
- from . import field_values as field_values_t
27
+ from uncountable.types import field_values as field_values_t
27
28
  import uncountable.types.api.recipes.get_curve as get_curve_t
28
29
  import uncountable.types.api.entity.get_entities_data as get_entities_data_t
29
30
  import uncountable.types.api.inputs.get_input_data as get_input_data_t
@@ -40,22 +41,27 @@ import uncountable.types.api.recipe_metadata.get_recipe_metadata_data as get_rec
40
41
  import uncountable.types.api.recipes.get_recipe_names as get_recipe_names_t
41
42
  import uncountable.types.api.recipes.get_recipe_output_metadata as get_recipe_output_metadata_t
42
43
  import uncountable.types.api.recipes.get_recipes_data as get_recipes_data_t
43
- from . import id_source as id_source_t
44
- from . import identifier as identifier_t
44
+ from uncountable.types import id_source as id_source_t
45
+ from uncountable.types import identifier as identifier_t
45
46
  import uncountable.types.api.entity.list_entities as list_entities_t
46
47
  import uncountable.types.api.id_source.list_id_source as list_id_source_t
47
48
  import uncountable.types.api.id_source.match_id_source as match_id_source_t
48
- from . import recipe_identifiers as recipe_identifiers_t
49
- from . import recipe_links as recipe_links_t
50
- from . import recipe_metadata as recipe_metadata_t
49
+ from uncountable.types import permissions as permissions_t
50
+ from uncountable.types import post_base as post_base_t
51
+ from uncountable.types import recipe_identifiers as recipe_identifiers_t
52
+ from uncountable.types import recipe_links as recipe_links_t
53
+ from uncountable.types import recipe_metadata as recipe_metadata_t
51
54
  import uncountable.types.api.entity.resolve_entity_ids as resolve_entity_ids_t
52
55
  import uncountable.types.api.outputs.resolve_output_conditions as resolve_output_conditions_t
53
56
  import uncountable.types.api.triggers.run_trigger as run_trigger_t
57
+ import uncountable.types.api.permissions.set_core_permissions as set_core_permissions_t
54
58
  import uncountable.types.api.inputs.set_input_attribute_values as set_input_attribute_values_t
55
59
  import uncountable.types.api.recipes.set_recipe_inputs as set_recipe_inputs_t
56
60
  import uncountable.types.api.recipes.set_recipe_metadata as set_recipe_metadata_t
57
61
  import uncountable.types.api.recipes.set_recipe_outputs as set_recipe_outputs_t
62
+ import uncountable.types.api.recipes.set_recipe_tags as set_recipe_tags_t
58
63
  import uncountable.types.api.entity.set_values as set_values_t
64
+ import uncountable.types.api.entity.transition_entity_phase as transition_entity_phase_t
59
65
  from abc import ABC, abstractmethod
60
66
  from dataclasses import dataclass
61
67
 
@@ -75,18 +81,20 @@ class ClientMethods(ABC):
75
81
  def do_request(self, *, api_request: APIRequest, return_type: type[DT]) -> DT:
76
82
  ...
77
83
 
78
-
79
84
  def associate_recipe_as_input(
80
85
  self,
81
86
  *,
82
87
  recipe_key: identifier_t.IdentifierKey,
88
+ input_key: typing.Optional[identifier_t.IdentifierKey] = None,
83
89
  ) -> associate_recipe_as_input_t.Data:
84
90
  """Create or return the input association for a recipe
85
91
 
86
92
  :param recipe_key: Identifier for the recipe
93
+ :param input_key: Identifier for an input to use for the association. Optionally supplied. If not supplied, one is created
87
94
  """
88
95
  args = associate_recipe_as_input_t.Arguments(
89
96
  recipe_key=recipe_key,
97
+ input_key=input_key,
90
98
  )
91
99
  api_request = APIRequest(
92
100
  method=associate_recipe_as_input_t.ENDPOINT_METHOD,
@@ -95,7 +103,6 @@ class ClientMethods(ABC):
95
103
  )
96
104
  return self.do_request(api_request=api_request, return_type=associate_recipe_as_input_t.Data)
97
105
 
98
-
99
106
  def associate_recipe_as_lot(
100
107
  self,
101
108
  *,
@@ -118,7 +125,6 @@ class ClientMethods(ABC):
118
125
  )
119
126
  return self.do_request(api_request=api_request, return_type=associate_recipe_as_lot_t.Data)
120
127
 
121
-
122
128
  def convert_chemical_formats(
123
129
  self,
124
130
  *,
@@ -137,12 +143,11 @@ class ClientMethods(ABC):
137
143
  )
138
144
  return self.do_request(api_request=api_request, return_type=convert_chemical_formats_t.Data)
139
145
 
140
-
141
146
  def create_entities(
142
147
  self,
143
148
  *,
144
149
  definition_id: base_t.ObjectId,
145
- entity_type: typing.Union[typing.Literal[entity_t.EntityType.LAB_REQUEST], typing.Literal[entity_t.EntityType.APPROVAL], typing.Literal[entity_t.EntityType.CUSTOM_ENTITY], typing.Literal[entity_t.EntityType.TASK], typing.Literal[entity_t.EntityType.PROJECT], typing.Literal[entity_t.EntityType.EQUIPMENT], typing.Literal[entity_t.EntityType.INV_LOCAL_LOCATIONS]],
150
+ entity_type: typing.Union[typing.Literal[entity_t.EntityType.LAB_REQUEST], typing.Literal[entity_t.EntityType.APPROVAL], typing.Literal[entity_t.EntityType.CUSTOM_ENTITY], typing.Literal[entity_t.EntityType.INVENTORY_AMOUNT], typing.Literal[entity_t.EntityType.TASK], typing.Literal[entity_t.EntityType.PROJECT], typing.Literal[entity_t.EntityType.EQUIPMENT], typing.Literal[entity_t.EntityType.INV_LOCAL_LOCATIONS], typing.Literal[entity_t.EntityType.FIELD_OPTION_SET], typing.Literal[entity_t.EntityType.WEBHOOK]],
146
151
  entities_to_create: list[create_entities_t.EntityToCreate],
147
152
  ) -> create_entities_t.Data:
148
153
  """Creates new Uncountable entities
@@ -163,12 +168,11 @@ class ClientMethods(ABC):
163
168
  )
164
169
  return self.do_request(api_request=api_request, return_type=create_entities_t.Data)
165
170
 
166
-
167
171
  def create_entity(
168
172
  self,
169
173
  *,
170
174
  definition_id: base_t.ObjectId,
171
- entity_type: typing.Union[typing.Literal[entity_t.EntityType.LAB_REQUEST], typing.Literal[entity_t.EntityType.APPROVAL], typing.Literal[entity_t.EntityType.CUSTOM_ENTITY], typing.Literal[entity_t.EntityType.TASK], typing.Literal[entity_t.EntityType.PROJECT], typing.Literal[entity_t.EntityType.EQUIPMENT], typing.Literal[entity_t.EntityType.INV_LOCAL_LOCATIONS]],
175
+ entity_type: typing.Union[typing.Literal[entity_t.EntityType.LAB_REQUEST], typing.Literal[entity_t.EntityType.APPROVAL], typing.Literal[entity_t.EntityType.CUSTOM_ENTITY], typing.Literal[entity_t.EntityType.INVENTORY_AMOUNT], typing.Literal[entity_t.EntityType.TASK], typing.Literal[entity_t.EntityType.PROJECT], typing.Literal[entity_t.EntityType.EQUIPMENT], typing.Literal[entity_t.EntityType.INV_LOCAL_LOCATIONS], typing.Literal[entity_t.EntityType.FIELD_OPTION_SET], typing.Literal[entity_t.EntityType.WEBHOOK]],
172
176
  field_values: typing.Optional[typing.Optional[list[field_values_t.FieldRefNameValue]]] = None,
173
177
  ) -> create_entity_t.Data:
174
178
  """Creates a new Uncountable entity
@@ -188,7 +192,6 @@ class ClientMethods(ABC):
188
192
  )
189
193
  return self.do_request(api_request=api_request, return_type=create_entity_t.Data)
190
194
 
191
-
192
195
  def external_create_inputs(
193
196
  self,
194
197
  *,
@@ -208,16 +211,15 @@ class ClientMethods(ABC):
208
211
  )
209
212
  return self.do_request(api_request=api_request, return_type=create_inputs_t.Data)
210
213
 
211
-
212
214
  def create_recipe(
213
215
  self,
214
216
  *,
215
217
  material_family_id: base_t.ObjectId,
216
218
  workflow_id: base_t.ObjectId,
217
- identifiers: recipe_identifiers_t.RecipeIdentifiers,
218
219
  name: typing.Optional[str] = None,
219
220
  workflow_variant_id: typing.Optional[typing.Optional[base_t.ObjectId]] = None,
220
221
  recipe_metadata: typing.Optional[list[recipe_metadata_t.MetadataValue]] = None,
222
+ identifiers: typing.Optional[recipe_identifiers_t.RecipeIdentifiers] = None,
221
223
  definition_key: typing.Optional[identifier_t.IdentifierKey] = None,
222
224
  ) -> create_recipe_t.Data:
223
225
  """Returns the id of the recipe being created.
@@ -246,7 +248,6 @@ class ClientMethods(ABC):
246
248
  )
247
249
  return self.do_request(api_request=api_request, return_type=create_recipe_t.Data)
248
250
 
249
-
250
251
  def create_recipe_link(
251
252
  self,
252
253
  *,
@@ -275,7 +276,6 @@ class ClientMethods(ABC):
275
276
  )
276
277
  return self.do_request(api_request=api_request, return_type=create_recipe_link_t.Data)
277
278
 
278
-
279
279
  def create_recipes(
280
280
  self,
281
281
  *,
@@ -300,6 +300,24 @@ class ClientMethods(ABC):
300
300
  )
301
301
  return self.do_request(api_request=api_request, return_type=create_recipes_t.Data)
302
302
 
303
+ def disassociate_recipe_as_input(
304
+ self,
305
+ *,
306
+ recipe_key: identifier_t.IdentifierKey,
307
+ ) -> disassociate_recipe_as_input_t.Data:
308
+ """Remove any association between a recipe and ingredients
309
+
310
+ :param recipe_key: Identifier for the recipe
311
+ """
312
+ args = disassociate_recipe_as_input_t.Arguments(
313
+ recipe_key=recipe_key,
314
+ )
315
+ api_request = APIRequest(
316
+ method=disassociate_recipe_as_input_t.ENDPOINT_METHOD,
317
+ endpoint=disassociate_recipe_as_input_t.ENDPOINT_PATH,
318
+ args=args,
319
+ )
320
+ return self.do_request(api_request=api_request, return_type=disassociate_recipe_as_input_t.Data)
303
321
 
304
322
  def execute_batch(
305
323
  self,
@@ -319,7 +337,6 @@ class ClientMethods(ABC):
319
337
  )
320
338
  return self.do_request(api_request=api_request, return_type=execute_batch_t.Data)
321
339
 
322
-
323
340
  def execute_batch_load_async(
324
341
  self,
325
342
  *,
@@ -338,18 +355,20 @@ class ClientMethods(ABC):
338
355
  )
339
356
  return self.do_request(api_request=api_request, return_type=execute_batch_load_async_t.Data)
340
357
 
341
-
342
358
  def get_curve(
343
359
  self,
344
360
  *,
345
- recipe_output_id: base_t.ObjectId,
361
+ recipe_output_id: typing.Optional[base_t.ObjectId] = None,
362
+ recipe_input_id: typing.Optional[base_t.ObjectId] = None,
346
363
  ) -> get_curve_t.Data:
347
364
  """Returns an array of values for the specified curve id.
348
365
 
349
366
  :param recipe_output_id: The recipe output ID to fetch the curve for. This must be a curve recipe output. Recipe Outputs can be found from external_get_recipes_data
367
+ :param recipe_input_id: The recipe input ID to fetch the curve for. This must be a curve recipe input. Recipe Inputs can be found from external_get_recipes_data
350
368
  """
351
369
  args = get_curve_t.Arguments(
352
370
  recipe_output_id=recipe_output_id,
371
+ recipe_input_id=recipe_input_id,
353
372
  )
354
373
  api_request = APIRequest(
355
374
  method=get_curve_t.ENDPOINT_METHOD,
@@ -358,7 +377,6 @@ class ClientMethods(ABC):
358
377
  )
359
378
  return self.do_request(api_request=api_request, return_type=get_curve_t.Data)
360
379
 
361
-
362
380
  def get_entities_data(
363
381
  self,
364
382
  *,
@@ -381,7 +399,6 @@ class ClientMethods(ABC):
381
399
  )
382
400
  return self.do_request(api_request=api_request, return_type=get_entities_data_t.Data)
383
401
 
384
-
385
402
  def get_input_data(
386
403
  self,
387
404
  *,
@@ -413,7 +430,6 @@ class ClientMethods(ABC):
413
430
  )
414
431
  return self.do_request(api_request=api_request, return_type=get_input_data_t.Data)
415
432
 
416
-
417
433
  def get_input_group_names(
418
434
  self,
419
435
  *,
@@ -433,7 +449,6 @@ class ClientMethods(ABC):
433
449
  )
434
450
  return self.do_request(api_request=api_request, return_type=get_input_group_names_t.Data)
435
451
 
436
-
437
452
  def get_input_names(
438
453
  self,
439
454
  *,
@@ -462,7 +477,6 @@ class ClientMethods(ABC):
462
477
  )
463
478
  return self.do_request(api_request=api_request, return_type=get_input_names_t.Data)
464
479
 
465
-
466
480
  def get_inputs_data(
467
481
  self,
468
482
  *,
@@ -482,7 +496,6 @@ class ClientMethods(ABC):
482
496
  )
483
497
  return self.do_request(api_request=api_request, return_type=get_inputs_data_t.Data)
484
498
 
485
-
486
499
  def get_output_data(
487
500
  self,
488
501
  *,
@@ -511,7 +524,6 @@ class ClientMethods(ABC):
511
524
  )
512
525
  return self.do_request(api_request=api_request, return_type=get_output_data_t.Data)
513
526
 
514
-
515
527
  def get_output_names(
516
528
  self,
517
529
  *,
@@ -537,7 +549,6 @@ class ClientMethods(ABC):
537
549
  )
538
550
  return self.do_request(api_request=api_request, return_type=get_output_names_t.Data)
539
551
 
540
-
541
552
  def get_projects(
542
553
  self,
543
554
  *,
@@ -560,7 +571,6 @@ class ClientMethods(ABC):
560
571
  )
561
572
  return self.do_request(api_request=api_request, return_type=get_projects_t.Data)
562
573
 
563
-
564
574
  def get_projects_data(
565
575
  self,
566
576
  *,
@@ -586,7 +596,6 @@ class ClientMethods(ABC):
586
596
  )
587
597
  return self.do_request(api_request=api_request, return_type=get_projects_data_t.Data)
588
598
 
589
-
590
599
  def get_recipe_calculations(
591
600
  self,
592
601
  *,
@@ -609,7 +618,6 @@ class ClientMethods(ABC):
609
618
  )
610
619
  return self.do_request(api_request=api_request, return_type=get_recipe_calculations_t.Data)
611
620
 
612
-
613
621
  def get_recipe_links(
614
622
  self,
615
623
  *,
@@ -635,7 +643,6 @@ class ClientMethods(ABC):
635
643
  )
636
644
  return self.do_request(api_request=api_request, return_type=get_recipe_links_t.Data)
637
645
 
638
-
639
646
  def get_recipe_metadata_data(
640
647
  self,
641
648
  *,
@@ -664,7 +671,6 @@ class ClientMethods(ABC):
664
671
  )
665
672
  return self.do_request(api_request=api_request, return_type=get_recipe_metadata_data_t.Data)
666
673
 
667
-
668
674
  def get_recipe_names(
669
675
  self,
670
676
  *,
@@ -684,7 +690,6 @@ class ClientMethods(ABC):
684
690
  )
685
691
  return self.do_request(api_request=api_request, return_type=get_recipe_names_t.Data)
686
692
 
687
-
688
693
  def get_recipe_output_metadata(
689
694
  self,
690
695
  *,
@@ -704,7 +709,6 @@ class ClientMethods(ABC):
704
709
  )
705
710
  return self.do_request(api_request=api_request, return_type=get_recipe_output_metadata_t.Data)
706
711
 
707
-
708
712
  def get_recipes_data(
709
713
  self,
710
714
  *,
@@ -733,7 +737,6 @@ class ClientMethods(ABC):
733
737
  )
734
738
  return self.do_request(api_request=api_request, return_type=get_recipes_data_t.Data)
735
739
 
736
-
737
740
  def list_entities(
738
741
  self,
739
742
  *,
@@ -765,7 +768,6 @@ class ClientMethods(ABC):
765
768
  )
766
769
  return self.do_request(api_request=api_request, return_type=list_entities_t.Data)
767
770
 
768
-
769
771
  def list_id_source(
770
772
  self,
771
773
  *,
@@ -794,7 +796,6 @@ class ClientMethods(ABC):
794
796
  )
795
797
  return self.do_request(api_request=api_request, return_type=list_id_source_t.Data)
796
798
 
797
-
798
799
  def match_id_source(
799
800
  self,
800
801
  *,
@@ -817,7 +818,6 @@ class ClientMethods(ABC):
817
818
  )
818
819
  return self.do_request(api_request=api_request, return_type=match_id_source_t.Data)
819
820
 
820
-
821
821
  def resolve_entity_ids(
822
822
  self,
823
823
  *,
@@ -840,7 +840,6 @@ class ClientMethods(ABC):
840
840
  )
841
841
  return self.do_request(api_request=api_request, return_type=resolve_entity_ids_t.Data)
842
842
 
843
-
844
843
  def resolve_output_conditions(
845
844
  self,
846
845
  *,
@@ -859,7 +858,6 @@ class ClientMethods(ABC):
859
858
  )
860
859
  return self.do_request(api_request=api_request, return_type=resolve_output_conditions_t.Data)
861
860
 
862
-
863
861
  def run_trigger(
864
862
  self,
865
863
  *,
@@ -880,6 +878,35 @@ class ClientMethods(ABC):
880
878
  )
881
879
  return self.do_request(api_request=api_request, return_type=run_trigger_t.Data)
882
880
 
881
+ def set_core_permissions(
882
+ self,
883
+ *,
884
+ scope: set_core_permissions_t.PermissionsScope,
885
+ permissions_types: list[permissions_t.CorePermissionType],
886
+ update_type: post_base_t.UpdateType,
887
+ user_group_ids: typing.Optional[list[int]] = None,
888
+ user_ids: typing.Optional[list[int]] = None,
889
+ ) -> set_core_permissions_t.Data:
890
+ """Sets recipe related permissions
891
+
892
+ :param scope: Scope of permissions to change
893
+ :param user_group_ids: User group ids to grant permission to
894
+ :param user_ids: User ids to grant permission to
895
+ :param update_type: The type of update to perform
896
+ """
897
+ args = set_core_permissions_t.Arguments(
898
+ scope=scope,
899
+ user_group_ids=user_group_ids,
900
+ user_ids=user_ids,
901
+ permissions_types=permissions_types,
902
+ update_type=update_type,
903
+ )
904
+ api_request = APIRequest(
905
+ method=set_core_permissions_t.ENDPOINT_METHOD,
906
+ endpoint=set_core_permissions_t.ENDPOINT_PATH,
907
+ args=args,
908
+ )
909
+ return self.do_request(api_request=api_request, return_type=set_core_permissions_t.Data)
883
910
 
884
911
  def set_input_attribute_values(
885
912
  self,
@@ -900,7 +927,6 @@ class ClientMethods(ABC):
900
927
  )
901
928
  return self.do_request(api_request=api_request, return_type=set_input_attribute_values_t.Data)
902
929
 
903
-
904
930
  def set_recipe_inputs(
905
931
  self,
906
932
  *,
@@ -920,7 +946,6 @@ class ClientMethods(ABC):
920
946
  )
921
947
  return self.do_request(api_request=api_request, return_type=set_recipe_inputs_t.Data)
922
948
 
923
-
924
949
  def set_recipe_metadata(
925
950
  self,
926
951
  *,
@@ -943,7 +968,6 @@ class ClientMethods(ABC):
943
968
  )
944
969
  return self.do_request(api_request=api_request, return_type=set_recipe_metadata_t.Data)
945
970
 
946
-
947
971
  def set_recipe_outputs(
948
972
  self,
949
973
  *,
@@ -963,6 +987,27 @@ class ClientMethods(ABC):
963
987
  )
964
988
  return self.do_request(api_request=api_request, return_type=set_recipe_outputs_t.Data)
965
989
 
990
+ def set_recipe_tags(
991
+ self,
992
+ *,
993
+ recipe_key: identifier_t.IdentifierKey,
994
+ recipe_tag_update: set_recipe_tags_t.RecipeTagUpdate,
995
+ ) -> set_recipe_tags_t.Data:
996
+ """Modifies recipes tags for a recipe
997
+
998
+ :param recipe_key: Identifier for the recipe
999
+ :param recipe_tag_update: The update to perform on the recipe tags
1000
+ """
1001
+ args = set_recipe_tags_t.Arguments(
1002
+ recipe_key=recipe_key,
1003
+ recipe_tag_update=recipe_tag_update,
1004
+ )
1005
+ api_request = APIRequest(
1006
+ method=set_recipe_tags_t.ENDPOINT_METHOD,
1007
+ endpoint=set_recipe_tags_t.ENDPOINT_PATH,
1008
+ args=args,
1009
+ )
1010
+ return self.do_request(api_request=api_request, return_type=set_recipe_tags_t.Data)
966
1011
 
967
1012
  def set_values(
968
1013
  self,
@@ -983,3 +1028,23 @@ class ClientMethods(ABC):
983
1028
  args=args,
984
1029
  )
985
1030
  return self.do_request(api_request=api_request, return_type=set_values_t.Data)
1031
+
1032
+ def transition_entity_phase(
1033
+ self,
1034
+ *,
1035
+ entity: entity_t.Entity,
1036
+ transition: transition_entity_phase_t.TransitionIdentifier,
1037
+ ) -> transition_entity_phase_t.Data:
1038
+ """Transitions an entity from one phase to another
1039
+
1040
+ """
1041
+ args = transition_entity_phase_t.Arguments(
1042
+ entity=entity,
1043
+ transition=transition,
1044
+ )
1045
+ api_request = APIRequest(
1046
+ method=transition_entity_phase_t.ENDPOINT_METHOD,
1047
+ endpoint=transition_entity_phase_t.ENDPOINT_PATH,
1048
+ args=args,
1049
+ )
1050
+ return self.do_request(api_request=api_request, return_type=transition_entity_phase_t.Data)
@@ -23,7 +23,7 @@ __all__: list[str] = [
23
23
  @serial_class(
24
24
  parse_require={"type"},
25
25
  )
26
- @dataclass(kw_only=True)
26
+ @dataclass(kw_only=True, frozen=True, eq=True)
27
27
  class IdentifierKeyId:
28
28
  type: typing.Literal["id"] = "id"
29
29
  id: base_t.ObjectId
@@ -33,7 +33,7 @@ class IdentifierKeyId:
33
33
  @serial_class(
34
34
  parse_require={"type"},
35
35
  )
36
- @dataclass(kw_only=True)
36
+ @dataclass(kw_only=True, frozen=True, eq=True)
37
37
  class IdentifierKeyRefName:
38
38
  type: typing.Literal["ref_name"] = "ref_name"
39
39
  ref_name: str
@@ -43,7 +43,7 @@ class IdentifierKeyRefName:
43
43
  @serial_class(
44
44
  parse_require={"type"},
45
45
  )
46
- @dataclass(kw_only=True)
46
+ @dataclass(kw_only=True, frozen=True, eq=True)
47
47
  class IdentifierKeyBatchReference:
48
48
  type: typing.Literal["batch_reference"] = "batch_reference"
49
49
  reference: str
@@ -0,0 +1,46 @@
1
+ # DO NOT MODIFY -- This file is generated by type_spec
2
+ # flake8: noqa: F821
3
+ # ruff: noqa: E402
4
+ # fmt: off
5
+ # isort: skip_file
6
+ from __future__ import annotations
7
+ import typing # noqa: F401
8
+ import datetime # noqa: F401
9
+ from decimal import Decimal # noqa: F401
10
+ from pkgs.strenum_compat import StrEnum
11
+ from pkgs.serialization import serial_string_enum
12
+
13
+ __all__: list[str] = [
14
+ "CorePermissionType",
15
+ ]
16
+
17
+
18
+ # DO NOT MODIFY -- This file is generated by type_spec
19
+ @serial_string_enum(
20
+ labels={
21
+ "admin_rights": "Admin Rights",
22
+ "read_ingredients": "View Ingredients",
23
+ "read_recipe_all": "View Entire Recipe",
24
+ "read_recipe_outputs": "View Recipe Outputs",
25
+ "view_material_family": "View Material Family",
26
+ "write_ingredients": "Modify Ingredients",
27
+ "write_outputs": "Modify Outputs",
28
+ "write_recipe_all": "Modify Entire Recipe",
29
+ "write_recipe_ingredients": "Modify Recipe Inputs",
30
+ "write_recipe_outputs": "Modify Recipe Outputs",
31
+ "add_recipe": "Create Experiments",
32
+ },
33
+ )
34
+ class CorePermissionType(StrEnum):
35
+ ADMIN_RIGHTS = "admin_rights"
36
+ READ_INGREDIENTS = "read_ingredients"
37
+ READ_RECIPE_ALL = "read_recipe_all"
38
+ READ_RECIPE_OUTPUTS = "read_recipe_outputs"
39
+ VIEW_MATERIAL_FAMILY = "view_material_family"
40
+ WRITE_INGREDIENTS = "write_ingredients"
41
+ WRITE_OUTPUTS = "write_outputs"
42
+ WRITE_RECIPE_ALL = "write_recipe_all"
43
+ WRITE_RECIPE_INGREDIENTS = "write_recipe_ingredients"
44
+ WRITE_RECIPE_OUTPUTS = "write_recipe_outputs"
45
+ ADD_RECIPE = "add_recipe"
46
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -0,0 +1,30 @@
1
+ # DO NOT MODIFY -- This file is generated by type_spec
2
+ # flake8: noqa: F821
3
+ # ruff: noqa: E402
4
+ # fmt: off
5
+ # isort: skip_file
6
+ from __future__ import annotations
7
+ import typing # noqa: F401
8
+ import datetime # noqa: F401
9
+ from decimal import Decimal # noqa: F401
10
+ from pkgs.strenum_compat import StrEnum
11
+ from pkgs.serialization import serial_string_enum
12
+
13
+ __all__: list[str] = [
14
+ "UpdateType",
15
+ ]
16
+
17
+
18
+ # DO NOT MODIFY -- This file is generated by type_spec
19
+ @serial_string_enum(
20
+ labels={
21
+ "append": "Append values",
22
+ "override": "Wipe existing and replace",
23
+ "remove": "Remove values",
24
+ },
25
+ )
26
+ class UpdateType(StrEnum):
27
+ APPEND = "append"
28
+ OVERRIDE = "override"
29
+ REMOVE = "remove"
30
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -0,0 +1,30 @@
1
+ # DO NOT MODIFY -- This file is generated by type_spec
2
+ # flake8: noqa: F821
3
+ # ruff: noqa: E402
4
+ # fmt: off
5
+ # isort: skip_file
6
+ from __future__ import annotations
7
+ import typing # noqa: F401
8
+ import datetime # noqa: F401
9
+ from decimal import Decimal # noqa: F401
10
+ from pkgs.strenum_compat import StrEnum
11
+
12
+ __all__: list[str] = [
13
+ "InputValueType",
14
+ "QuantityBasis",
15
+ ]
16
+
17
+
18
+ # DO NOT MODIFY -- This file is generated by type_spec
19
+ class InputValueType(StrEnum):
20
+ VALUE = "value"
21
+ ACTUAL_VALUE = "actual_value"
22
+
23
+
24
+ # DO NOT MODIFY -- This file is generated by type_spec
25
+ class QuantityBasis(StrEnum):
26
+ ARBITRARY = "arbitrary"
27
+ MASS = "mass"
28
+ MOLES = "moles"
29
+ VOLUME = "volume"
30
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -20,6 +20,7 @@ __all__: list[str] = [
20
20
 
21
21
  # DO NOT MODIFY -- This file is generated by type_spec
22
22
  @serial_class(
23
+ unconverted_values={"value_json"},
23
24
  to_string_values={"value_numeric"},
24
25
  )
25
26
  @dataclass(kw_only=True)
@@ -27,6 +28,7 @@ class MetadataValue:
27
28
  metadata_id: base_t.ObjectId
28
29
  value_numeric: typing.Optional[Decimal] = None
29
30
  value_str: typing.Optional[str] = None
31
+ value_json: typing.Optional[base_t.JsonValue] = None
30
32
 
31
33
 
32
34
  # DO NOT MODIFY -- This file is generated by type_spec