UncountablePythonSDK 0.0.83__py3-none-any.whl → 0.0.132__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 (298) hide show
  1. docs/conf.py +54 -7
  2. docs/index.md +107 -4
  3. docs/integration_examples/create_ingredient.md +43 -0
  4. docs/integration_examples/create_output.md +56 -0
  5. docs/integration_examples/index.md +6 -0
  6. docs/justfile +2 -2
  7. docs/requirements.txt +6 -4
  8. examples/basic_auth.py +7 -0
  9. examples/create_ingredient_sdk.py +34 -0
  10. examples/download_files.py +26 -0
  11. examples/integration-server/jobs/materials_auto/concurrent_cron.py +11 -0
  12. examples/integration-server/jobs/materials_auto/example_cron.py +3 -0
  13. examples/integration-server/jobs/materials_auto/example_http.py +47 -0
  14. examples/integration-server/jobs/materials_auto/example_instrument.py +100 -0
  15. examples/integration-server/jobs/materials_auto/example_parse.py +140 -0
  16. examples/integration-server/jobs/materials_auto/example_predictions.py +61 -0
  17. examples/integration-server/jobs/materials_auto/example_runsheet_wh.py +39 -0
  18. examples/integration-server/jobs/materials_auto/example_wh.py +17 -9
  19. examples/integration-server/jobs/materials_auto/profile.yaml +61 -0
  20. examples/integration-server/pyproject.toml +10 -10
  21. examples/oauth.py +7 -0
  22. examples/set_recipe_metadata_file.py +1 -1
  23. examples/upload_files.py +1 -2
  24. pkgs/argument_parser/__init__.py +8 -0
  25. pkgs/argument_parser/_is_namedtuple.py +3 -0
  26. pkgs/argument_parser/argument_parser.py +196 -63
  27. pkgs/filesystem_utils/__init__.py +1 -0
  28. pkgs/filesystem_utils/_blob_session.py +144 -0
  29. pkgs/filesystem_utils/_gdrive_session.py +5 -5
  30. pkgs/filesystem_utils/_s3_session.py +2 -1
  31. pkgs/filesystem_utils/_sftp_session.py +6 -3
  32. pkgs/filesystem_utils/file_type_utils.py +30 -10
  33. pkgs/serialization/__init__.py +7 -2
  34. pkgs/serialization/annotation.py +64 -0
  35. pkgs/serialization/missing_sentry.py +1 -1
  36. pkgs/serialization/opaque_key.py +1 -1
  37. pkgs/serialization/serial_alias.py +47 -0
  38. pkgs/serialization/serial_class.py +40 -48
  39. pkgs/serialization/serial_generic.py +16 -0
  40. pkgs/serialization/serial_union.py +16 -16
  41. pkgs/serialization_util/__init__.py +6 -0
  42. pkgs/serialization_util/dataclasses.py +14 -0
  43. pkgs/serialization_util/serialization_helpers.py +15 -5
  44. pkgs/type_spec/actions_registry/__main__.py +0 -4
  45. pkgs/type_spec/actions_registry/emit_typescript.py +2 -4
  46. pkgs/type_spec/builder.py +248 -70
  47. pkgs/type_spec/builder_types.py +9 -0
  48. pkgs/type_spec/config.py +40 -7
  49. pkgs/type_spec/cross_output_links.py +99 -0
  50. pkgs/type_spec/emit_open_api.py +121 -34
  51. pkgs/type_spec/emit_open_api_util.py +5 -5
  52. pkgs/type_spec/emit_python.py +277 -86
  53. pkgs/type_spec/emit_typescript.py +102 -29
  54. pkgs/type_spec/emit_typescript_util.py +66 -10
  55. pkgs/type_spec/load_types.py +16 -3
  56. pkgs/type_spec/non_discriminated_union_exceptions.py +14 -0
  57. pkgs/type_spec/open_api_util.py +29 -4
  58. pkgs/type_spec/parts/base.py.prepart +11 -8
  59. pkgs/type_spec/parts/base.ts.prepart +4 -0
  60. pkgs/type_spec/type_info/__main__.py +3 -1
  61. pkgs/type_spec/type_info/emit_type_info.py +115 -22
  62. pkgs/type_spec/ui_entry_actions/__init__.py +4 -0
  63. pkgs/type_spec/ui_entry_actions/generate_ui_entry_actions.py +308 -0
  64. pkgs/type_spec/util.py +3 -3
  65. pkgs/type_spec/value_spec/__main__.py +26 -9
  66. pkgs/type_spec/value_spec/convert_type.py +18 -0
  67. pkgs/type_spec/value_spec/emit_python.py +13 -3
  68. pkgs/type_spec/value_spec/types.py +1 -1
  69. uncountable/core/async_batch.py +1 -1
  70. uncountable/core/client.py +133 -34
  71. uncountable/core/environment.py +3 -3
  72. uncountable/core/file_upload.py +39 -15
  73. uncountable/integration/cli.py +116 -23
  74. uncountable/integration/construct_client.py +3 -3
  75. uncountable/integration/executors/executors.py +12 -2
  76. uncountable/integration/executors/generic_upload_executor.py +66 -14
  77. uncountable/integration/http_server/__init__.py +5 -0
  78. uncountable/integration/http_server/types.py +69 -0
  79. uncountable/integration/job.py +192 -7
  80. uncountable/integration/queue_runner/command_server/__init__.py +4 -0
  81. uncountable/integration/queue_runner/command_server/command_client.py +65 -0
  82. uncountable/integration/queue_runner/command_server/command_server.py +83 -5
  83. uncountable/integration/queue_runner/command_server/constants.py +4 -0
  84. uncountable/integration/queue_runner/command_server/protocol/command_server.proto +36 -0
  85. uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.py +28 -11
  86. uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.pyi +77 -1
  87. uncountable/integration/queue_runner/command_server/protocol/command_server_pb2_grpc.py +135 -0
  88. uncountable/integration/queue_runner/command_server/types.py +25 -2
  89. uncountable/integration/queue_runner/datastore/datastore_sqlite.py +168 -11
  90. uncountable/integration/queue_runner/datastore/interface.py +10 -0
  91. uncountable/integration/queue_runner/datastore/model.py +8 -1
  92. uncountable/integration/queue_runner/job_scheduler.py +63 -23
  93. uncountable/integration/queue_runner/queue_runner.py +10 -2
  94. uncountable/integration/queue_runner/worker.py +3 -5
  95. uncountable/integration/scan_profiles.py +1 -1
  96. uncountable/integration/scheduler.py +74 -25
  97. uncountable/integration/secret_retrieval/retrieve_secret.py +1 -1
  98. uncountable/integration/server.py +42 -12
  99. uncountable/integration/telemetry.py +63 -10
  100. uncountable/integration/webhook_server/entrypoint.py +39 -112
  101. uncountable/types/__init__.py +58 -1
  102. uncountable/types/api/batch/execute_batch.py +5 -6
  103. uncountable/types/api/batch/execute_batch_load_async.py +2 -3
  104. uncountable/types/api/chemical/convert_chemical_formats.py +10 -5
  105. uncountable/types/api/condition_parameters/__init__.py +1 -0
  106. uncountable/types/api/condition_parameters/upsert_condition_match.py +72 -0
  107. uncountable/types/api/entity/create_entities.py +7 -7
  108. uncountable/types/api/entity/create_entity.py +8 -8
  109. uncountable/types/api/entity/create_or_update_entity.py +48 -0
  110. uncountable/types/api/entity/export_entities.py +59 -0
  111. uncountable/types/api/entity/get_entities_data.py +3 -4
  112. uncountable/types/api/entity/grant_entity_permissions.py +6 -6
  113. uncountable/types/api/entity/list_aggregate.py +79 -0
  114. uncountable/types/api/entity/list_entities.py +34 -10
  115. uncountable/types/api/entity/lock_entity.py +4 -4
  116. uncountable/types/api/entity/lookup_entity.py +116 -0
  117. uncountable/types/api/entity/resolve_entity_ids.py +5 -6
  118. uncountable/types/api/entity/set_entity_field_values.py +44 -0
  119. uncountable/types/api/entity/set_values.py +3 -3
  120. uncountable/types/api/entity/transition_entity_phase.py +14 -7
  121. uncountable/types/api/entity/unlock_entity.py +3 -3
  122. uncountable/types/api/equipment/associate_equipment_input.py +2 -3
  123. uncountable/types/api/field_options/upsert_field_options.py +7 -7
  124. uncountable/types/api/files/__init__.py +1 -0
  125. uncountable/types/api/files/download_file.py +77 -0
  126. uncountable/types/api/id_source/list_id_source.py +6 -7
  127. uncountable/types/api/id_source/match_id_source.py +4 -5
  128. uncountable/types/api/input_groups/get_input_group_names.py +3 -4
  129. uncountable/types/api/inputs/create_inputs.py +10 -9
  130. uncountable/types/api/inputs/get_input_data.py +11 -12
  131. uncountable/types/api/inputs/get_input_names.py +6 -7
  132. uncountable/types/api/inputs/get_inputs_data.py +6 -7
  133. uncountable/types/api/inputs/set_input_attribute_values.py +5 -6
  134. uncountable/types/api/inputs/set_input_category.py +5 -5
  135. uncountable/types/api/inputs/set_input_subcategories.py +3 -3
  136. uncountable/types/api/inputs/set_intermediate_type.py +4 -4
  137. uncountable/types/api/integrations/__init__.py +1 -0
  138. uncountable/types/api/integrations/publish_realtime_data.py +41 -0
  139. uncountable/types/api/integrations/push_notification.py +49 -0
  140. uncountable/types/api/integrations/register_sockets_token.py +41 -0
  141. uncountable/types/api/listing/__init__.py +1 -0
  142. uncountable/types/api/listing/fetch_listing.py +58 -0
  143. uncountable/types/api/material_families/update_entity_material_families.py +3 -4
  144. uncountable/types/api/notebooks/__init__.py +1 -0
  145. uncountable/types/api/notebooks/add_notebook_content.py +119 -0
  146. uncountable/types/api/outputs/get_output_data.py +12 -13
  147. uncountable/types/api/outputs/get_output_names.py +5 -6
  148. uncountable/types/api/outputs/get_output_organization.py +173 -0
  149. uncountable/types/api/outputs/resolve_output_conditions.py +7 -8
  150. uncountable/types/api/permissions/set_core_permissions.py +16 -10
  151. uncountable/types/api/project/get_projects.py +6 -7
  152. uncountable/types/api/project/get_projects_data.py +7 -8
  153. uncountable/types/api/recipe_links/create_recipe_link.py +5 -5
  154. uncountable/types/api/recipe_links/remove_recipe_link.py +4 -4
  155. uncountable/types/api/recipe_metadata/get_recipe_metadata_data.py +6 -7
  156. uncountable/types/api/recipes/add_recipe_to_project.py +3 -3
  157. uncountable/types/api/recipes/add_time_series_data.py +64 -0
  158. uncountable/types/api/recipes/archive_recipes.py +4 -4
  159. uncountable/types/api/recipes/associate_recipe_as_input.py +5 -5
  160. uncountable/types/api/recipes/associate_recipe_as_lot.py +3 -3
  161. uncountable/types/api/recipes/clear_recipe_outputs.py +3 -3
  162. uncountable/types/api/recipes/create_mix_order.py +44 -0
  163. uncountable/types/api/recipes/create_recipe.py +8 -9
  164. uncountable/types/api/recipes/create_recipes.py +8 -9
  165. uncountable/types/api/recipes/disassociate_recipe_as_input.py +3 -3
  166. uncountable/types/api/recipes/edit_recipe_inputs.py +101 -24
  167. uncountable/types/api/recipes/get_column_calculation_values.py +4 -5
  168. uncountable/types/api/recipes/get_curve.py +4 -5
  169. uncountable/types/api/recipes/get_recipe_calculations.py +6 -7
  170. uncountable/types/api/recipes/get_recipe_links.py +3 -4
  171. uncountable/types/api/recipes/get_recipe_names.py +3 -4
  172. uncountable/types/api/recipes/get_recipe_output_metadata.py +5 -6
  173. uncountable/types/api/recipes/get_recipes_data.py +62 -34
  174. uncountable/types/api/recipes/lock_recipes.py +9 -8
  175. uncountable/types/api/recipes/remove_recipe_from_project.py +3 -3
  176. uncountable/types/api/recipes/set_recipe_inputs.py +9 -10
  177. uncountable/types/api/recipes/set_recipe_metadata.py +3 -3
  178. uncountable/types/api/recipes/set_recipe_output_annotations.py +11 -12
  179. uncountable/types/api/recipes/set_recipe_output_file.py +5 -6
  180. uncountable/types/api/recipes/set_recipe_outputs.py +24 -13
  181. uncountable/types/api/recipes/set_recipe_tags.py +14 -9
  182. uncountable/types/api/recipes/set_recipe_total.py +59 -0
  183. uncountable/types/api/recipes/unarchive_recipes.py +3 -3
  184. uncountable/types/api/recipes/unlock_recipes.py +7 -6
  185. uncountable/types/api/runsheet/__init__.py +1 -0
  186. uncountable/types/api/runsheet/complete_async_upload.py +41 -0
  187. uncountable/types/api/triggers/run_trigger.py +4 -4
  188. uncountable/types/api/uploader/complete_async_parse.py +46 -0
  189. uncountable/types/api/uploader/invoke_uploader.py +4 -5
  190. uncountable/types/api/user/__init__.py +1 -0
  191. uncountable/types/api/user/get_current_user_info.py +40 -0
  192. uncountable/types/async_batch.py +1 -1
  193. uncountable/types/async_batch_processor.py +506 -23
  194. uncountable/types/async_batch_t.py +35 -8
  195. uncountable/types/async_jobs.py +0 -1
  196. uncountable/types/async_jobs_t.py +1 -2
  197. uncountable/types/auth_retrieval.py +0 -1
  198. uncountable/types/auth_retrieval_t.py +6 -6
  199. uncountable/types/base.py +0 -1
  200. uncountable/types/base_t.py +11 -9
  201. uncountable/types/calculations.py +0 -1
  202. uncountable/types/calculations_t.py +1 -2
  203. uncountable/types/chemical_structure.py +0 -1
  204. uncountable/types/chemical_structure_t.py +5 -5
  205. uncountable/types/client_base.py +614 -69
  206. uncountable/types/client_config.py +1 -1
  207. uncountable/types/client_config_t.py +13 -3
  208. uncountable/types/curves.py +0 -1
  209. uncountable/types/curves_t.py +6 -7
  210. uncountable/types/data.py +12 -0
  211. uncountable/types/data_t.py +103 -0
  212. uncountable/types/entity.py +1 -1
  213. uncountable/types/entity_t.py +90 -10
  214. uncountable/types/experiment_groups.py +0 -1
  215. uncountable/types/experiment_groups_t.py +1 -2
  216. uncountable/types/exports.py +8 -0
  217. uncountable/types/exports_t.py +34 -0
  218. uncountable/types/field_values.py +19 -1
  219. uncountable/types/field_values_t.py +242 -9
  220. uncountable/types/fields.py +0 -1
  221. uncountable/types/fields_t.py +1 -2
  222. uncountable/types/generic_upload.py +0 -1
  223. uncountable/types/generic_upload_t.py +14 -14
  224. uncountable/types/id_source.py +0 -1
  225. uncountable/types/id_source_t.py +13 -7
  226. uncountable/types/identifier.py +0 -1
  227. uncountable/types/identifier_t.py +10 -5
  228. uncountable/types/input_attributes.py +0 -1
  229. uncountable/types/input_attributes_t.py +3 -4
  230. uncountable/types/inputs.py +0 -1
  231. uncountable/types/inputs_t.py +3 -4
  232. uncountable/types/integration_server.py +0 -1
  233. uncountable/types/integration_server_t.py +13 -4
  234. uncountable/types/integration_session.py +10 -0
  235. uncountable/types/integration_session_t.py +60 -0
  236. uncountable/types/integrations.py +10 -0
  237. uncountable/types/integrations_t.py +62 -0
  238. uncountable/types/job_definition.py +2 -1
  239. uncountable/types/job_definition_t.py +57 -32
  240. uncountable/types/listing.py +9 -0
  241. uncountable/types/listing_t.py +51 -0
  242. uncountable/types/notices.py +8 -0
  243. uncountable/types/notices_t.py +37 -0
  244. uncountable/types/notifications.py +11 -0
  245. uncountable/types/notifications_t.py +74 -0
  246. uncountable/types/outputs.py +0 -1
  247. uncountable/types/outputs_t.py +2 -3
  248. uncountable/types/overrides.py +0 -1
  249. uncountable/types/overrides_t.py +10 -4
  250. uncountable/types/permissions.py +0 -1
  251. uncountable/types/permissions_t.py +1 -2
  252. uncountable/types/phases.py +0 -1
  253. uncountable/types/phases_t.py +1 -2
  254. uncountable/types/post_base.py +0 -1
  255. uncountable/types/post_base_t.py +1 -2
  256. uncountable/types/queued_job.py +2 -1
  257. uncountable/types/queued_job_t.py +29 -12
  258. uncountable/types/recipe_identifiers.py +0 -1
  259. uncountable/types/recipe_identifiers_t.py +18 -8
  260. uncountable/types/recipe_inputs.py +0 -1
  261. uncountable/types/recipe_inputs_t.py +1 -2
  262. uncountable/types/recipe_links.py +0 -1
  263. uncountable/types/recipe_links_t.py +3 -4
  264. uncountable/types/recipe_metadata.py +0 -1
  265. uncountable/types/recipe_metadata_t.py +9 -10
  266. uncountable/types/recipe_output_metadata.py +0 -1
  267. uncountable/types/recipe_output_metadata_t.py +1 -2
  268. uncountable/types/recipe_tags.py +0 -1
  269. uncountable/types/recipe_tags_t.py +1 -2
  270. uncountable/types/recipe_workflow_steps.py +0 -1
  271. uncountable/types/recipe_workflow_steps_t.py +7 -7
  272. uncountable/types/recipes.py +0 -1
  273. uncountable/types/recipes_t.py +2 -2
  274. uncountable/types/response.py +0 -1
  275. uncountable/types/response_t.py +2 -2
  276. uncountable/types/secret_retrieval.py +0 -1
  277. uncountable/types/secret_retrieval_t.py +7 -7
  278. uncountable/types/sockets.py +20 -0
  279. uncountable/types/sockets_t.py +169 -0
  280. uncountable/types/structured_filters.py +25 -0
  281. uncountable/types/structured_filters_t.py +248 -0
  282. uncountable/types/units.py +0 -1
  283. uncountable/types/units_t.py +1 -2
  284. uncountable/types/uploader.py +24 -0
  285. uncountable/types/uploader_t.py +222 -0
  286. uncountable/types/users.py +0 -1
  287. uncountable/types/users_t.py +1 -2
  288. uncountable/types/webhook_job.py +1 -1
  289. uncountable/types/webhook_job_t.py +14 -3
  290. uncountable/types/workflows.py +0 -1
  291. uncountable/types/workflows_t.py +3 -4
  292. uncountablepythonsdk-0.0.132.dist-info/METADATA +64 -0
  293. uncountablepythonsdk-0.0.132.dist-info/RECORD +363 -0
  294. {UncountablePythonSDK-0.0.83.dist-info → uncountablepythonsdk-0.0.132.dist-info}/WHEEL +1 -1
  295. UncountablePythonSDK-0.0.83.dist-info/METADATA +0 -60
  296. UncountablePythonSDK-0.0.83.dist-info/RECORD +0 -292
  297. docs/quickstart.md +0 -19
  298. {UncountablePythonSDK-0.0.83.dist-info → uncountablepythonsdk-0.0.132.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,64 @@
1
+ # DO NOT MODIFY -- This file is generated by type_spec
2
+ # ruff: noqa: E402 Q003
3
+ # fmt: off
4
+ # isort: skip_file
5
+ from __future__ import annotations
6
+ import typing # noqa: F401
7
+ import datetime # noqa: F401
8
+ from decimal import Decimal # noqa: F401
9
+ from enum import StrEnum
10
+ import dataclasses
11
+ from pkgs.serialization import serial_class
12
+ from ... import async_batch_t
13
+ from ... import base_t
14
+ from ... import identifier_t
15
+
16
+ __all__: list[str] = [
17
+ "Arguments",
18
+ "Data",
19
+ "ENDPOINT_METHOD",
20
+ "ENDPOINT_PATH",
21
+ "OnTimepointConflict",
22
+ "TimeSeriesDatum",
23
+ ]
24
+
25
+ ENDPOINT_METHOD = "POST"
26
+ ENDPOINT_PATH = "api/external/recipes/external_add_time_series_data"
27
+
28
+
29
+ # DO NOT MODIFY -- This file is generated by type_spec
30
+ class OnTimepointConflict(StrEnum):
31
+ OVERWRITE = "overwrite"
32
+ ERROR = "error"
33
+
34
+
35
+ # DO NOT MODIFY -- This file is generated by type_spec
36
+ @serial_class(
37
+ named_type_path="sdk.api.recipes.add_time_series_data.TimeSeriesDatum",
38
+ to_string_values={"value"},
39
+ )
40
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
41
+ class TimeSeriesDatum:
42
+ timestamp: datetime.datetime
43
+ value: Decimal | None = None
44
+
45
+
46
+ # DO NOT MODIFY -- This file is generated by type_spec
47
+ @serial_class(
48
+ named_type_path="sdk.api.recipes.add_time_series_data.Arguments",
49
+ )
50
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
51
+ class Arguments:
52
+ time_series_segment_key: identifier_t.IdentifierKey
53
+ time_series_data: list[TimeSeriesDatum]
54
+ on_conflict: OnTimepointConflict = OnTimepointConflict.ERROR
55
+
56
+
57
+ # DO NOT MODIFY -- This file is generated by type_spec
58
+ @serial_class(
59
+ named_type_path="sdk.api.recipes.add_time_series_data.Data",
60
+ )
61
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
62
+ class Data(async_batch_t.AsyncBatchActionReturn):
63
+ pass
64
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -1,5 +1,4 @@
1
1
  # DO NOT MODIFY -- This file is generated by type_spec
2
- # flake8: noqa: F821
3
2
  # ruff: noqa: E402 Q003
4
3
  # fmt: off
5
4
  # isort: skip_file
@@ -9,6 +8,7 @@ import datetime # noqa: F401
9
8
  from decimal import Decimal # noqa: F401
10
9
  import dataclasses
11
10
  from pkgs.serialization import serial_class
11
+ from ... import base_t
12
12
  from ... import identifier_t
13
13
 
14
14
  __all__: list[str] = [
@@ -26,17 +26,17 @@ ENDPOINT_PATH = "api/external/recipes/archive"
26
26
  @serial_class(
27
27
  named_type_path="sdk.api.recipes.archive_recipes.Arguments",
28
28
  )
29
- @dataclasses.dataclass(kw_only=True)
29
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
30
30
  class Arguments:
31
31
  recipes: list[identifier_t.IdentifierKey]
32
- reason: typing.Optional[str] = None
32
+ reason: str | None = None
33
33
 
34
34
 
35
35
  # DO NOT MODIFY -- This file is generated by type_spec
36
36
  @serial_class(
37
37
  named_type_path="sdk.api.recipes.archive_recipes.Data",
38
38
  )
39
- @dataclasses.dataclass(kw_only=True)
39
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
40
40
  class Data:
41
41
  pass
42
42
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -1,5 +1,4 @@
1
1
  # DO NOT MODIFY -- This file is generated by type_spec
2
- # flake8: noqa: F821
3
2
  # ruff: noqa: E402 Q003
4
3
  # fmt: off
5
4
  # isort: skip_file
@@ -10,6 +9,7 @@ from decimal import Decimal # noqa: F401
10
9
  import dataclasses
11
10
  from pkgs.serialization import serial_class
12
11
  from ... import async_batch_t
12
+ from ... import base_t
13
13
  from ... import identifier_t
14
14
 
15
15
  __all__: list[str] = [
@@ -27,18 +27,18 @@ ENDPOINT_PATH = "api/external/recipes/associate_recipe_as_input"
27
27
  @serial_class(
28
28
  named_type_path="sdk.api.recipes.associate_recipe_as_input.Arguments",
29
29
  )
30
- @dataclasses.dataclass(kw_only=True)
30
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
31
31
  class Arguments:
32
32
  recipe_key: identifier_t.IdentifierKey
33
- input_key: typing.Optional[identifier_t.IdentifierKey] = None
34
- show_in_listings: typing.Optional[bool] = None
33
+ input_key: identifier_t.IdentifierKey | None = None
34
+ show_in_listings: bool | None = None
35
35
 
36
36
 
37
37
  # DO NOT MODIFY -- This file is generated by type_spec
38
38
  @serial_class(
39
39
  named_type_path="sdk.api.recipes.associate_recipe_as_input.Data",
40
40
  )
41
- @dataclasses.dataclass(kw_only=True)
41
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
42
42
  class Data(async_batch_t.AsyncBatchActionReturn):
43
43
  pass
44
44
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -1,5 +1,4 @@
1
1
  # DO NOT MODIFY -- This file is generated by type_spec
2
- # flake8: noqa: F821
3
2
  # ruff: noqa: E402 Q003
4
3
  # fmt: off
5
4
  # isort: skip_file
@@ -10,6 +9,7 @@ from decimal import Decimal # noqa: F401
10
9
  import dataclasses
11
10
  from pkgs.serialization import serial_class
12
11
  from ... import async_batch_t
12
+ from ... import base_t
13
13
  from ... import identifier_t
14
14
 
15
15
  __all__: list[str] = [
@@ -27,7 +27,7 @@ ENDPOINT_PATH = "api/external/recipes/associate_recipe_as_lot"
27
27
  @serial_class(
28
28
  named_type_path="sdk.api.recipes.associate_recipe_as_lot.Arguments",
29
29
  )
30
- @dataclasses.dataclass(kw_only=True)
30
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
31
31
  class Arguments:
32
32
  recipe_key: identifier_t.IdentifierKey
33
33
  ingredient_key: identifier_t.IdentifierKey
@@ -37,7 +37,7 @@ class Arguments:
37
37
  @serial_class(
38
38
  named_type_path="sdk.api.recipes.associate_recipe_as_lot.Data",
39
39
  )
40
- @dataclasses.dataclass(kw_only=True)
40
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
41
41
  class Data(async_batch_t.AsyncBatchActionReturn):
42
42
  pass
43
43
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -1,5 +1,4 @@
1
1
  # DO NOT MODIFY -- This file is generated by type_spec
2
- # flake8: noqa: F821
3
2
  # ruff: noqa: E402 Q003
4
3
  # fmt: off
5
4
  # isort: skip_file
@@ -10,6 +9,7 @@ from decimal import Decimal # noqa: F401
10
9
  import dataclasses
11
10
  from pkgs.serialization import serial_class
12
11
  from ... import async_batch_t
12
+ from ... import base_t
13
13
  from ... import identifier_t
14
14
 
15
15
  __all__: list[str] = [
@@ -27,7 +27,7 @@ ENDPOINT_PATH = "api/external/recipes/clear_recipe_outputs"
27
27
  @serial_class(
28
28
  named_type_path="sdk.api.recipes.clear_recipe_outputs.Arguments",
29
29
  )
30
- @dataclasses.dataclass(kw_only=True)
30
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
31
31
  class Arguments:
32
32
  recipe_key: identifier_t.IdentifierKey
33
33
 
@@ -36,7 +36,7 @@ class Arguments:
36
36
  @serial_class(
37
37
  named_type_path="sdk.api.recipes.clear_recipe_outputs.Data",
38
38
  )
39
- @dataclasses.dataclass(kw_only=True)
39
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
40
40
  class Data(async_batch_t.AsyncBatchActionReturn):
41
41
  pass
42
42
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -0,0 +1,44 @@
1
+ # DO NOT MODIFY -- This file is generated by type_spec
2
+ # ruff: noqa: E402 Q003
3
+ # fmt: off
4
+ # isort: skip_file
5
+ from __future__ import annotations
6
+ import typing # noqa: F401
7
+ import datetime # noqa: F401
8
+ from decimal import Decimal # noqa: F401
9
+ import dataclasses
10
+ from pkgs.serialization import serial_class
11
+ from ... import async_batch_t
12
+ from ... import base_t
13
+ from ... import identifier_t
14
+ from ... import recipe_workflow_steps_t
15
+
16
+ __all__: list[str] = [
17
+ "Arguments",
18
+ "Data",
19
+ "ENDPOINT_METHOD",
20
+ "ENDPOINT_PATH",
21
+ ]
22
+
23
+ ENDPOINT_METHOD = "POST"
24
+ ENDPOINT_PATH = "api/external/recipes/create_mix_order"
25
+
26
+
27
+ # DO NOT MODIFY -- This file is generated by type_spec
28
+ @serial_class(
29
+ named_type_path="sdk.api.recipes.create_mix_order.Arguments",
30
+ )
31
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
32
+ class Arguments:
33
+ recipe_key: identifier_t.IdentifierKey
34
+ recipe_workflow_step_identifier: recipe_workflow_steps_t.RecipeWorkflowStepIdentifier
35
+
36
+
37
+ # DO NOT MODIFY -- This file is generated by type_spec
38
+ @serial_class(
39
+ named_type_path="sdk.api.recipes.create_mix_order.Data",
40
+ )
41
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
42
+ class Data(async_batch_t.AsyncBatchActionReturn):
43
+ pass
44
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -1,5 +1,4 @@
1
1
  # DO NOT MODIFY -- This file is generated by type_spec
2
- # flake8: noqa: F821
3
2
  # ruff: noqa: E402 Q003
4
3
  # fmt: off
5
4
  # isort: skip_file
@@ -29,23 +28,23 @@ ENDPOINT_PATH = "api/external/recipes/create_recipe"
29
28
  @serial_class(
30
29
  named_type_path="sdk.api.recipes.create_recipe.Arguments",
31
30
  )
32
- @dataclasses.dataclass(kw_only=True)
31
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
33
32
  class Arguments:
34
33
  material_family_id: base_t.ObjectId
35
34
  workflow_id: base_t.ObjectId
36
- name: typing.Optional[str] = None
37
- project_id: typing.Optional[base_t.ObjectId] = None
38
- workflow_variant_id: typing.Optional[typing.Optional[base_t.ObjectId]] = None
39
- recipe_metadata: typing.Optional[list[recipe_metadata_t.MetadataValue]] = None
40
- identifiers: typing.Optional[recipe_identifiers_t.RecipeIdentifiers] = None
41
- definition_key: typing.Optional[identifier_t.IdentifierKey] = None
35
+ name: str | None = None
36
+ project_id: base_t.ObjectId | None = None
37
+ workflow_variant_id: base_t.ObjectId | None = None
38
+ recipe_metadata: list[recipe_metadata_t.MetadataValue] | None = None
39
+ identifiers: recipe_identifiers_t.RecipeIdentifiers | None = None
40
+ definition_key: identifier_t.IdentifierKey | None = None
42
41
 
43
42
 
44
43
  # DO NOT MODIFY -- This file is generated by type_spec
45
44
  @serial_class(
46
45
  named_type_path="sdk.api.recipes.create_recipe.Data",
47
46
  )
48
- @dataclasses.dataclass(kw_only=True)
47
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
49
48
  class Data:
50
49
  result_id: base_t.ObjectId
51
50
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -1,5 +1,4 @@
1
1
  # DO NOT MODIFY -- This file is generated by type_spec
2
- # flake8: noqa: F821
3
2
  # ruff: noqa: E402 Q003
4
3
  # fmt: off
5
4
  # isort: skip_file
@@ -29,30 +28,30 @@ ENDPOINT_PATH = "api/external/recipes/external_create_recipes"
29
28
  @serial_class(
30
29
  named_type_path="sdk.api.recipes.create_recipes.CreateRecipeDefinition",
31
30
  )
32
- @dataclasses.dataclass(kw_only=True)
31
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
33
32
  class CreateRecipeDefinition:
34
33
  workflow_id: base_t.ObjectId
35
- name: typing.Optional[str] = None
36
- workflow_variant_id: typing.Optional[typing.Optional[base_t.ObjectId]] = None
37
- recipe_metadata: typing.Optional[list[recipe_metadata_t.MetadataValue]] = None
34
+ name: str | None = None
35
+ workflow_variant_id: base_t.ObjectId | None = None
36
+ recipe_metadata: list[recipe_metadata_t.MetadataValue] | None = None
38
37
 
39
38
 
40
39
  # DO NOT MODIFY -- This file is generated by type_spec
41
40
  @serial_class(
42
41
  named_type_path="sdk.api.recipes.create_recipes.Arguments",
43
42
  )
44
- @dataclasses.dataclass(kw_only=True)
43
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
45
44
  class Arguments:
46
45
  material_family_id: base_t.ObjectId
47
46
  recipe_definitions: list[CreateRecipeDefinition]
48
- project_id: typing.Optional[base_t.ObjectId] = None
47
+ project_id: base_t.ObjectId | None = None
49
48
 
50
49
 
51
50
  # DO NOT MODIFY -- This file is generated by type_spec
52
51
  @serial_class(
53
52
  named_type_path="sdk.api.recipes.create_recipes.CreateRecipeResult",
54
53
  )
55
- @dataclasses.dataclass(kw_only=True)
54
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
56
55
  class CreateRecipeResult:
57
56
  recipe_id: base_t.ObjectId
58
57
 
@@ -61,7 +60,7 @@ class CreateRecipeResult:
61
60
  @serial_class(
62
61
  named_type_path="sdk.api.recipes.create_recipes.Data",
63
62
  )
64
- @dataclasses.dataclass(kw_only=True)
63
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
65
64
  class Data:
66
65
  recipes: list[CreateRecipeResult]
67
66
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -1,5 +1,4 @@
1
1
  # DO NOT MODIFY -- This file is generated by type_spec
2
- # flake8: noqa: F821
3
2
  # ruff: noqa: E402 Q003
4
3
  # fmt: off
5
4
  # isort: skip_file
@@ -10,6 +9,7 @@ from decimal import Decimal # noqa: F401
10
9
  import dataclasses
11
10
  from pkgs.serialization import serial_class
12
11
  from ... import async_batch_t
12
+ from ... import base_t
13
13
  from ... import identifier_t
14
14
 
15
15
  __all__: list[str] = [
@@ -27,7 +27,7 @@ ENDPOINT_PATH = "api/external/recipes/disassociate_recipe_as_input"
27
27
  @serial_class(
28
28
  named_type_path="sdk.api.recipes.disassociate_recipe_as_input.Arguments",
29
29
  )
30
- @dataclasses.dataclass(kw_only=True)
30
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
31
31
  class Arguments:
32
32
  recipe_key: identifier_t.IdentifierKey
33
33
 
@@ -36,7 +36,7 @@ class Arguments:
36
36
  @serial_class(
37
37
  named_type_path="sdk.api.recipes.disassociate_recipe_as_input.Data",
38
38
  )
39
- @dataclasses.dataclass(kw_only=True)
39
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
40
40
  class Data(async_batch_t.AsyncBatchActionReturn):
41
41
  pass
42
42
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -1,5 +1,4 @@
1
1
  # DO NOT MODIFY -- This file is generated by type_spec
2
- # flake8: noqa: F821
3
2
  # ruff: noqa: E402 Q003
4
3
  # fmt: off
5
4
  # isort: skip_file
@@ -7,10 +6,11 @@ from __future__ import annotations
7
6
  import typing # noqa: F401
8
7
  import datetime # noqa: F401
9
8
  from decimal import Decimal # noqa: F401
10
- from pkgs.strenum_compat import StrEnum
9
+ from enum import StrEnum
11
10
  import dataclasses
12
11
  from pkgs.serialization import serial_class
13
12
  from pkgs.serialization import serial_union_annotation
13
+ from ... import base_t
14
14
  from ... import identifier_t
15
15
  from ... import inputs_t
16
16
  from ... import recipe_inputs_t
@@ -22,6 +22,10 @@ __all__: list[str] = [
22
22
  "Data",
23
23
  "ENDPOINT_METHOD",
24
24
  "ENDPOINT_PATH",
25
+ "MixStepMatchStrategy",
26
+ "PlaceholderBase",
27
+ "PlaceholderDisplayMode",
28
+ "PlaceholderType",
25
29
  "RecipeInputEdit",
26
30
  "RecipeInputEditAddInput",
27
31
  "RecipeInputEditAddInstructions",
@@ -29,11 +33,14 @@ __all__: list[str] = [
29
33
  "RecipeInputEditChangeBasisViewed",
30
34
  "RecipeInputEditClearInputs",
31
35
  "RecipeInputEditInputBase",
36
+ "RecipeInputEditPlaceholder",
32
37
  "RecipeInputEditSetLot",
33
38
  "RecipeInputEditSetRole",
34
39
  "RecipeInputEditType",
35
40
  "RecipeInputEditUpdateAnnotations",
36
41
  "RecipeInputEditUpsertInput",
42
+ "RecipeInputPlaceholder",
43
+ "SubcategoryPlaceholder",
37
44
  ]
38
45
 
39
46
  ENDPOINT_METHOD = "POST"
@@ -50,13 +57,20 @@ class RecipeInputEditType(StrEnum):
50
57
  CHANGE_BASIS = "change_basis"
51
58
  ADD_INSTRUCTIONS = "add_instructions"
52
59
  SET_ROLE = "set_role"
60
+ SET_PLACEHOLDER = "set_placeholder"
61
+
62
+
63
+ # DO NOT MODIFY -- This file is generated by type_spec
64
+ class MixStepMatchStrategy(StrEnum):
65
+ FIRST = "first"
66
+ LAST = "last"
53
67
 
54
68
 
55
69
  # DO NOT MODIFY -- This file is generated by type_spec
56
70
  @serial_class(
57
71
  named_type_path="sdk.api.recipes.edit_recipe_inputs.RecipeInputEditBase",
58
72
  )
59
- @dataclasses.dataclass(kw_only=True)
73
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
60
74
  class RecipeInputEditBase:
61
75
  type: RecipeInputEditType
62
76
 
@@ -66,7 +80,7 @@ class RecipeInputEditBase:
66
80
  named_type_path="sdk.api.recipes.edit_recipe_inputs.RecipeInputEditClearInputs",
67
81
  parse_require={"type"},
68
82
  )
69
- @dataclasses.dataclass(kw_only=True)
83
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
70
84
  class RecipeInputEditClearInputs(RecipeInputEditBase):
71
85
  type: typing.Literal[RecipeInputEditType.CLEAR_INPUTS] = RecipeInputEditType.CLEAR_INPUTS
72
86
 
@@ -76,15 +90,15 @@ class RecipeInputEditClearInputs(RecipeInputEditBase):
76
90
  named_type_path="sdk.api.recipes.edit_recipe_inputs.RecipeInputEditInputBase",
77
91
  to_string_values={"value_numeric"},
78
92
  )
79
- @dataclasses.dataclass(kw_only=True)
93
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
80
94
  class RecipeInputEditInputBase(RecipeInputEditBase):
81
95
  ingredient_key: identifier_t.IdentifierKey
82
- quantity_basis: recipe_inputs_t.QuantityBasis = recipe_inputs_t.QuantityBasis.MASS
96
+ quantity_basis: recipe_inputs_t.QuantityBasis | None = recipe_inputs_t.QuantityBasis.MASS
83
97
  input_value_type: recipe_inputs_t.InputValueType = recipe_inputs_t.InputValueType.VALUE
84
- value_numeric: typing.Optional[Decimal] = None
85
- value_str: typing.Optional[str] = None
86
- behavior: typing.Optional[inputs_t.IngredientBehavior] = None
87
- calculation_key: typing.Optional[identifier_t.IdentifierKey] = None
98
+ value_numeric: Decimal | None = None
99
+ value_str: str | None = None
100
+ behavior: inputs_t.IngredientBehavior | None = None
101
+ calculation_key: identifier_t.IdentifierKey | None = None
88
102
 
89
103
 
90
104
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -92,9 +106,10 @@ class RecipeInputEditInputBase(RecipeInputEditBase):
92
106
  named_type_path="sdk.api.recipes.edit_recipe_inputs.RecipeInputEditChangeBasisViewed",
93
107
  parse_require={"type"},
94
108
  )
95
- @dataclasses.dataclass(kw_only=True)
109
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
96
110
  class RecipeInputEditChangeBasisViewed(RecipeInputEditInputBase):
97
111
  type: typing.Literal[RecipeInputEditType.CHANGE_BASIS] = RecipeInputEditType.CHANGE_BASIS
112
+ mix_step_match_strategy: MixStepMatchStrategy = MixStepMatchStrategy.FIRST
98
113
 
99
114
 
100
115
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -102,10 +117,11 @@ class RecipeInputEditChangeBasisViewed(RecipeInputEditInputBase):
102
117
  named_type_path="sdk.api.recipes.edit_recipe_inputs.RecipeInputEditUpsertInput",
103
118
  parse_require={"type"},
104
119
  )
105
- @dataclasses.dataclass(kw_only=True)
120
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
106
121
  class RecipeInputEditUpsertInput(RecipeInputEditInputBase):
107
122
  type: typing.Literal[RecipeInputEditType.UPSERT_INPUT] = RecipeInputEditType.UPSERT_INPUT
108
123
  clear_first: bool
124
+ mix_step_match_strategy: MixStepMatchStrategy = MixStepMatchStrategy.FIRST
109
125
 
110
126
 
111
127
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -113,7 +129,7 @@ class RecipeInputEditUpsertInput(RecipeInputEditInputBase):
113
129
  named_type_path="sdk.api.recipes.edit_recipe_inputs.RecipeInputEditAddInput",
114
130
  parse_require={"type"},
115
131
  )
116
- @dataclasses.dataclass(kw_only=True)
132
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
117
133
  class RecipeInputEditAddInput(RecipeInputEditInputBase):
118
134
  type: typing.Literal[RecipeInputEditType.ADD_INPUT] = RecipeInputEditType.ADD_INPUT
119
135
 
@@ -123,11 +139,12 @@ class RecipeInputEditAddInput(RecipeInputEditInputBase):
123
139
  named_type_path="sdk.api.recipes.edit_recipe_inputs.RecipeInputEditSetLot",
124
140
  parse_require={"type"},
125
141
  )
126
- @dataclasses.dataclass(kw_only=True)
142
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
127
143
  class RecipeInputEditSetLot(RecipeInputEditBase):
128
144
  type: typing.Literal[RecipeInputEditType.SET_LOT] = RecipeInputEditType.SET_LOT
129
145
  ingredient_key: identifier_t.IdentifierKey
130
146
  ingredient_lot_recipe_key: identifier_t.IdentifierKey
147
+ mix_step_match_strategy: MixStepMatchStrategy = MixStepMatchStrategy.FIRST
131
148
 
132
149
 
133
150
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -135,7 +152,7 @@ class RecipeInputEditSetLot(RecipeInputEditBase):
135
152
  named_type_path="sdk.api.recipes.edit_recipe_inputs.RecipeInputEditAddInstructions",
136
153
  parse_require={"type"},
137
154
  )
138
- @dataclasses.dataclass(kw_only=True)
155
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
139
156
  class RecipeInputEditAddInstructions(RecipeInputEditBase):
140
157
  type: typing.Literal[RecipeInputEditType.ADD_INSTRUCTIONS] = RecipeInputEditType.ADD_INSTRUCTIONS
141
158
  instructions: str
@@ -146,11 +163,11 @@ class RecipeInputEditAddInstructions(RecipeInputEditBase):
146
163
  named_type_path="sdk.api.recipes.edit_recipe_inputs.AnnotationEdit",
147
164
  to_string_values={"lower_value", "upper_value"},
148
165
  )
149
- @dataclasses.dataclass(kw_only=True)
166
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
150
167
  class AnnotationEdit:
151
168
  annotation_type_key: identifier_t.IdentifierKey
152
- lower_value: typing.Optional[Decimal] = None
153
- upper_value: typing.Optional[Decimal] = None
169
+ lower_value: Decimal | None = None
170
+ upper_value: Decimal | None = None
154
171
 
155
172
 
156
173
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -158,11 +175,12 @@ class AnnotationEdit:
158
175
  named_type_path="sdk.api.recipes.edit_recipe_inputs.RecipeInputEditUpdateAnnotations",
159
176
  parse_require={"type"},
160
177
  )
161
- @dataclasses.dataclass(kw_only=True)
178
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
162
179
  class RecipeInputEditUpdateAnnotations(RecipeInputEditInputBase):
163
180
  type: typing.Literal[RecipeInputEditType.UPDATE_ANNOTATIONS] = RecipeInputEditType.UPDATE_ANNOTATIONS
164
181
  clear_first: bool
165
182
  annotations: list[AnnotationEdit]
183
+ mix_step_match_strategy: MixStepMatchStrategy = MixStepMatchStrategy.FIRST
166
184
 
167
185
 
168
186
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -170,16 +188,74 @@ class RecipeInputEditUpdateAnnotations(RecipeInputEditInputBase):
170
188
  named_type_path="sdk.api.recipes.edit_recipe_inputs.RecipeInputEditSetRole",
171
189
  parse_require={"type"},
172
190
  )
173
- @dataclasses.dataclass(kw_only=True)
191
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
174
192
  class RecipeInputEditSetRole(RecipeInputEditBase):
175
193
  type: typing.Literal[RecipeInputEditType.SET_ROLE] = RecipeInputEditType.SET_ROLE
176
194
  ingredient_key: identifier_t.IdentifierKey
177
- ingredient_role_key: typing.Optional[identifier_t.IdentifierKey]
195
+ ingredient_role_key: identifier_t.IdentifierKey | None
196
+
197
+
198
+ # DO NOT MODIFY -- This file is generated by type_spec
199
+ class PlaceholderType(StrEnum):
200
+ SUBCATEGORY = "subcategory"
201
+
202
+
203
+ # DO NOT MODIFY -- This file is generated by type_spec
204
+ class PlaceholderDisplayMode(StrEnum):
205
+ INLINE = "inline"
206
+
207
+
208
+ # DO NOT MODIFY -- This file is generated by type_spec
209
+ @serial_class(
210
+ named_type_path="sdk.api.recipes.edit_recipe_inputs.PlaceholderBase",
211
+ )
212
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
213
+ class PlaceholderBase:
214
+ type: PlaceholderType
215
+ require_for_creation: bool = True
216
+ display_mode: PlaceholderDisplayMode = PlaceholderDisplayMode.INLINE
217
+
218
+
219
+ # DO NOT MODIFY -- This file is generated by type_spec
220
+ @serial_class(
221
+ named_type_path="sdk.api.recipes.edit_recipe_inputs.SubcategoryPlaceholder",
222
+ parse_require={"type"},
223
+ )
224
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
225
+ class SubcategoryPlaceholder(PlaceholderBase):
226
+ type: typing.Literal[PlaceholderType.SUBCATEGORY] = PlaceholderType.SUBCATEGORY
227
+ subcategory_identifier: identifier_t.IdentifierKey
228
+
229
+
230
+ # DO NOT MODIFY -- This file is generated by type_spec
231
+ RecipeInputPlaceholder = typing.Annotated[
232
+ typing.Union[SubcategoryPlaceholder],
233
+ serial_union_annotation(
234
+ named_type_path="sdk.api.recipes.edit_recipe_inputs.RecipeInputPlaceholder",
235
+ discriminator="type",
236
+ discriminator_map={
237
+ "subcategory": SubcategoryPlaceholder,
238
+ },
239
+ ),
240
+ ]
241
+
242
+
243
+ # DO NOT MODIFY -- This file is generated by type_spec
244
+ @serial_class(
245
+ named_type_path="sdk.api.recipes.edit_recipe_inputs.RecipeInputEditPlaceholder",
246
+ parse_require={"type"},
247
+ )
248
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
249
+ class RecipeInputEditPlaceholder(RecipeInputEditBase):
250
+ type: typing.Literal[RecipeInputEditType.SET_PLACEHOLDER] = RecipeInputEditType.SET_PLACEHOLDER
251
+ ingredient_key: identifier_t.IdentifierKey
252
+ placeholder: RecipeInputPlaceholder
253
+ mix_step_match_strategy: MixStepMatchStrategy = MixStepMatchStrategy.FIRST
178
254
 
179
255
 
180
256
  # DO NOT MODIFY -- This file is generated by type_spec
181
257
  RecipeInputEdit = typing.Annotated[
182
- typing.Union[RecipeInputEditClearInputs, RecipeInputEditUpsertInput, RecipeInputEditAddInput, RecipeInputEditUpdateAnnotations, RecipeInputEditSetLot, RecipeInputEditChangeBasisViewed, RecipeInputEditAddInstructions, RecipeInputEditSetRole],
258
+ RecipeInputEditClearInputs | RecipeInputEditUpsertInput | RecipeInputEditAddInput | RecipeInputEditUpdateAnnotations | RecipeInputEditSetLot | RecipeInputEditChangeBasisViewed | RecipeInputEditAddInstructions | RecipeInputEditSetRole | RecipeInputEditPlaceholder,
183
259
  serial_union_annotation(
184
260
  named_type_path="sdk.api.recipes.edit_recipe_inputs.RecipeInputEdit",
185
261
  discriminator="type",
@@ -192,6 +268,7 @@ RecipeInputEdit = typing.Annotated[
192
268
  "change_basis": RecipeInputEditChangeBasisViewed,
193
269
  "add_instructions": RecipeInputEditAddInstructions,
194
270
  "set_role": RecipeInputEditSetRole,
271
+ "set_placeholder": RecipeInputEditPlaceholder,
195
272
  },
196
273
  ),
197
274
  ]
@@ -201,7 +278,7 @@ RecipeInputEdit = typing.Annotated[
201
278
  @serial_class(
202
279
  named_type_path="sdk.api.recipes.edit_recipe_inputs.Arguments",
203
280
  )
204
- @dataclasses.dataclass(kw_only=True)
281
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
205
282
  class Arguments:
206
283
  recipe_key: identifier_t.IdentifierKey
207
284
  recipe_workflow_step_identifier: recipe_workflow_steps_t.RecipeWorkflowStepIdentifier
@@ -212,7 +289,7 @@ class Arguments:
212
289
  @serial_class(
213
290
  named_type_path="sdk.api.recipes.edit_recipe_inputs.Data",
214
291
  )
215
- @dataclasses.dataclass(kw_only=True)
292
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
216
293
  class Data:
217
294
  pass
218
295
  # DO NOT MODIFY -- This file is generated by type_spec