UncountablePythonSDK 0.0.82__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 +22 -17
  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.82.dist-info → uncountablepythonsdk-0.0.132.dist-info}/WHEEL +1 -1
  295. UncountablePythonSDK-0.0.82.dist-info/METADATA +0 -60
  296. UncountablePythonSDK-0.0.82.dist-info/RECORD +0 -292
  297. docs/quickstart.md +0 -19
  298. {UncountablePythonSDK-0.0.82.dist-info → uncountablepythonsdk-0.0.132.dist-info}/top_level.txt +0 -0
@@ -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
@@ -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
@@ -28,7 +27,7 @@ ENDPOINT_PATH = "api/external/recipes/get_column_calculation_values"
28
27
  @serial_class(
29
28
  named_type_path="sdk.api.recipes.get_column_calculation_values.Arguments",
30
29
  )
31
- @dataclasses.dataclass(kw_only=True)
30
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
32
31
  class Arguments:
33
32
  recipe_keys: list[identifier_t.IdentifierKey]
34
33
  calculation_key: identifier_t.IdentifierKey
@@ -39,20 +38,20 @@ class Arguments:
39
38
  named_type_path="sdk.api.recipes.get_column_calculation_values.RecipeColumnCalculationValue",
40
39
  to_string_values={"calculation_quantity"},
41
40
  )
42
- @dataclasses.dataclass(kw_only=True)
41
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
43
42
  class RecipeColumnCalculationValue:
44
43
  recipe_id: base_t.ObjectId
45
44
  ingredient_id: base_t.ObjectId
46
45
  recipe_step_id: base_t.ObjectId
47
46
  recipe_input_id: base_t.ObjectId
48
- calculation_quantity: typing.Optional[Decimal] = None
47
+ calculation_quantity: Decimal | 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.get_column_calculation_values.Data",
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 Data:
57
56
  values: list[RecipeColumnCalculationValue]
58
57
  # 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
@@ -27,17 +26,17 @@ ENDPOINT_PATH = "api/external/recipes/external_get_curve"
27
26
  @serial_class(
28
27
  named_type_path="sdk.api.recipes.get_curve.Arguments",
29
28
  )
30
- @dataclasses.dataclass(kw_only=True)
29
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
31
30
  class Arguments:
32
- recipe_output_id: typing.Optional[base_t.ObjectId] = None
33
- recipe_input_id: typing.Optional[base_t.ObjectId] = None
31
+ recipe_output_id: base_t.ObjectId | None = None
32
+ recipe_input_id: base_t.ObjectId | None = None
34
33
 
35
34
 
36
35
  # DO NOT MODIFY -- This file is generated by type_spec
37
36
  @serial_class(
38
37
  named_type_path="sdk.api.recipes.get_curve.Data",
39
38
  )
40
- @dataclasses.dataclass(kw_only=True)
39
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
41
40
  class Data:
42
41
  curve: curves_t.Curve
43
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
@@ -28,10 +27,10 @@ ENDPOINT_PATH = "api/external/recipes/external_get_recipe_calculations"
28
27
  @serial_class(
29
28
  named_type_path="sdk.api.recipes.get_recipe_calculations.Arguments",
30
29
  )
31
- @dataclasses.dataclass(kw_only=True)
30
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
32
31
  class Arguments:
33
32
  recipe_ids: list[base_t.ObjectId]
34
- calculation_ids: typing.Optional[list[base_t.ObjectId]] = None
33
+ calculation_ids: list[base_t.ObjectId] | None = None
35
34
 
36
35
 
37
36
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -40,19 +39,19 @@ class Arguments:
40
39
  unconverted_values={"quantity_json"},
41
40
  to_string_values={"quantity_dec"},
42
41
  )
43
- @dataclasses.dataclass(kw_only=True)
42
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
44
43
  class RecipeCalculation:
45
44
  recipe_id: base_t.ObjectId
46
45
  calculation_id: base_t.ObjectId
47
- quantity_dec: typing.Optional[Decimal] = None
48
- quantity_json: typing.Optional[base_t.JsonValue] = None
46
+ quantity_dec: Decimal | None = None
47
+ quantity_json: base_t.JsonValue | 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.get_recipe_calculations.Data",
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 Data:
57
56
  recipe_calculations: list[RecipeCalculation]
58
57
  calculations: list[calculations_t.Calculation]
@@ -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
@@ -27,18 +26,18 @@ ENDPOINT_PATH = "api/external/recipes/external_get_recipe_links"
27
26
  @serial_class(
28
27
  named_type_path="sdk.api.recipes.get_recipe_links.Arguments",
29
28
  )
30
- @dataclasses.dataclass(kw_only=True)
29
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
31
30
  class Arguments:
32
31
  recipe_ids: list[base_t.ObjectId]
33
32
  depth: int = 1
34
- link_types: typing.Optional[list[recipe_links_t.RecipeLinkType]]
33
+ link_types: list[recipe_links_t.RecipeLinkType] | None
35
34
 
36
35
 
37
36
  # DO NOT MODIFY -- This file is generated by type_spec
38
37
  @serial_class(
39
38
  named_type_path="sdk.api.recipes.get_recipe_links.Data",
40
39
  )
41
- @dataclasses.dataclass(kw_only=True)
40
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
42
41
  class Data:
43
42
  recipe_links: list[recipe_links_t.RecipeLink]
44
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
@@ -27,7 +26,7 @@ ENDPOINT_PATH = "api/external/recipes/external_get_recipe_names"
27
26
  @serial_class(
28
27
  named_type_path="sdk.api.recipes.get_recipe_names.Arguments",
29
28
  )
30
- @dataclasses.dataclass(kw_only=True)
29
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
31
30
  class Arguments:
32
31
  project_id: base_t.ObjectId
33
32
 
@@ -36,7 +35,7 @@ class Arguments:
36
35
  @serial_class(
37
36
  named_type_path="sdk.api.recipes.get_recipe_names.SimpleRecipe",
38
37
  )
39
- @dataclasses.dataclass(kw_only=True)
38
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
40
39
  class SimpleRecipe:
41
40
  id: base_t.ObjectId
42
41
  name: str
@@ -46,7 +45,7 @@ class SimpleRecipe:
46
45
  @serial_class(
47
46
  named_type_path="sdk.api.recipes.get_recipe_names.Data",
48
47
  )
49
- @dataclasses.dataclass(kw_only=True)
48
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
50
49
  class Data:
51
50
  recipes: list[SimpleRecipe]
52
51
  # 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
@@ -28,7 +27,7 @@ ENDPOINT_PATH = "api/external/recipes/external_get_recipe_output_metadata"
28
27
  @serial_class(
29
28
  named_type_path="sdk.api.recipes.get_recipe_output_metadata.Arguments",
30
29
  )
31
- @dataclasses.dataclass(kw_only=True)
30
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
32
31
  class Arguments:
33
32
  recipe_output_ids: list[base_t.ObjectId]
34
33
 
@@ -39,19 +38,19 @@ class Arguments:
39
38
  unconverted_values={"quantity_json"},
40
39
  to_string_values={"quantity_dec"},
41
40
  )
42
- @dataclasses.dataclass(kw_only=True)
41
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
43
42
  class RecipeOutputMetadata:
44
43
  recipe_output_id: base_t.ObjectId
45
44
  recipe_output_metadata_field_id: base_t.ObjectId
46
- quantity_dec: Decimal
47
- quantity_json: base_t.JsonValue
45
+ quantity_dec: Decimal | None = None
46
+ quantity_json: base_t.JsonValue | None = None
48
47
 
49
48
 
50
49
  # DO NOT MODIFY -- This file is generated by type_spec
51
50
  @serial_class(
52
51
  named_type_path="sdk.api.recipes.get_recipe_output_metadata.Data",
53
52
  )
54
- @dataclasses.dataclass(kw_only=True)
53
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
55
54
  class Data:
56
55
  recipe_output_metadata: list[RecipeOutputMetadata]
57
56
  recipe_output_metadata_fields: list[recipe_output_metadata_t.RecipeOutputMetadataField]