UncountablePythonSDK 0.0.115__py3-none-any.whl → 0.0.142.dev0__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 (119) hide show
  1. docs/conf.py +52 -5
  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 +1 -1
  7. docs/requirements.txt +3 -2
  8. examples/basic_auth.py +7 -0
  9. examples/integration-server/jobs/materials_auto/example_cron.py +3 -0
  10. examples/integration-server/jobs/materials_auto/example_http.py +19 -7
  11. examples/integration-server/jobs/materials_auto/example_instrument.py +100 -0
  12. examples/integration-server/jobs/materials_auto/example_parse.py +140 -0
  13. examples/integration-server/jobs/materials_auto/example_predictions.py +61 -0
  14. examples/integration-server/jobs/materials_auto/example_runsheet_wh.py +57 -16
  15. examples/integration-server/jobs/materials_auto/profile.yaml +27 -0
  16. examples/integration-server/pyproject.toml +4 -4
  17. examples/oauth.py +7 -0
  18. pkgs/argument_parser/__init__.py +1 -0
  19. pkgs/argument_parser/_is_namedtuple.py +3 -0
  20. pkgs/argument_parser/argument_parser.py +22 -3
  21. pkgs/serialization_util/serialization_helpers.py +3 -1
  22. pkgs/type_spec/builder.py +66 -19
  23. pkgs/type_spec/builder_types.py +9 -0
  24. pkgs/type_spec/config.py +26 -5
  25. pkgs/type_spec/cross_output_links.py +10 -16
  26. pkgs/type_spec/emit_open_api.py +72 -22
  27. pkgs/type_spec/emit_open_api_util.py +1 -0
  28. pkgs/type_spec/emit_python.py +76 -12
  29. pkgs/type_spec/emit_typescript.py +48 -32
  30. pkgs/type_spec/emit_typescript_util.py +44 -6
  31. pkgs/type_spec/load_types.py +2 -2
  32. pkgs/type_spec/open_api_util.py +16 -1
  33. pkgs/type_spec/parts/base.ts.prepart +4 -0
  34. pkgs/type_spec/type_info/emit_type_info.py +37 -4
  35. pkgs/type_spec/ui_entry_actions/generate_ui_entry_actions.py +1 -0
  36. pkgs/type_spec/value_spec/__main__.py +2 -2
  37. pkgs/type_spec/value_spec/emit_python.py +6 -1
  38. uncountable/core/client.py +10 -3
  39. uncountable/integration/cli.py +175 -23
  40. uncountable/integration/executors/executors.py +1 -2
  41. uncountable/integration/executors/generic_upload_executor.py +1 -1
  42. uncountable/integration/http_server/types.py +3 -1
  43. uncountable/integration/job.py +35 -3
  44. uncountable/integration/queue_runner/command_server/__init__.py +4 -0
  45. uncountable/integration/queue_runner/command_server/command_client.py +89 -0
  46. uncountable/integration/queue_runner/command_server/command_server.py +117 -5
  47. uncountable/integration/queue_runner/command_server/constants.py +4 -0
  48. uncountable/integration/queue_runner/command_server/protocol/command_server.proto +51 -0
  49. uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.py +34 -11
  50. uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.pyi +102 -1
  51. uncountable/integration/queue_runner/command_server/protocol/command_server_pb2_grpc.py +180 -0
  52. uncountable/integration/queue_runner/command_server/types.py +44 -1
  53. uncountable/integration/queue_runner/datastore/datastore_sqlite.py +189 -8
  54. uncountable/integration/queue_runner/datastore/interface.py +13 -0
  55. uncountable/integration/queue_runner/datastore/model.py +8 -1
  56. uncountable/integration/queue_runner/job_scheduler.py +85 -21
  57. uncountable/integration/queue_runner/queue_runner.py +10 -2
  58. uncountable/integration/queue_runner/types.py +2 -0
  59. uncountable/integration/queue_runner/worker.py +28 -29
  60. uncountable/integration/scheduler.py +121 -23
  61. uncountable/integration/server.py +36 -6
  62. uncountable/integration/telemetry.py +129 -8
  63. uncountable/integration/webhook_server/entrypoint.py +2 -0
  64. uncountable/types/__init__.py +38 -0
  65. uncountable/types/api/entity/create_or_update_entity.py +1 -0
  66. uncountable/types/api/entity/export_entities.py +13 -0
  67. uncountable/types/api/entity/list_aggregate.py +79 -0
  68. uncountable/types/api/entity/list_entities.py +25 -0
  69. uncountable/types/api/entity/set_barcode.py +43 -0
  70. uncountable/types/api/entity/transition_entity_phase.py +2 -1
  71. uncountable/types/api/files/download_file.py +15 -1
  72. uncountable/types/api/integrations/__init__.py +1 -0
  73. uncountable/types/api/integrations/publish_realtime_data.py +41 -0
  74. uncountable/types/api/integrations/push_notification.py +49 -0
  75. uncountable/types/api/integrations/register_sockets_token.py +41 -0
  76. uncountable/types/api/listing/__init__.py +1 -0
  77. uncountable/types/api/listing/fetch_listing.py +57 -0
  78. uncountable/types/api/notebooks/__init__.py +1 -0
  79. uncountable/types/api/notebooks/add_notebook_content.py +119 -0
  80. uncountable/types/api/outputs/get_output_organization.py +173 -0
  81. uncountable/types/api/recipes/edit_recipe_inputs.py +1 -1
  82. uncountable/types/api/recipes/get_recipe_output_metadata.py +2 -2
  83. uncountable/types/api/recipes/get_recipes_data.py +29 -0
  84. uncountable/types/api/recipes/lock_recipes.py +2 -1
  85. uncountable/types/api/recipes/set_recipe_total.py +59 -0
  86. uncountable/types/api/recipes/unlock_recipes.py +2 -1
  87. uncountable/types/api/runsheet/export_default_runsheet.py +44 -0
  88. uncountable/types/api/uploader/complete_async_parse.py +46 -0
  89. uncountable/types/api/user/__init__.py +1 -0
  90. uncountable/types/api/user/get_current_user_info.py +40 -0
  91. uncountable/types/async_batch_processor.py +266 -0
  92. uncountable/types/async_batch_t.py +5 -0
  93. uncountable/types/client_base.py +432 -2
  94. uncountable/types/client_config.py +1 -0
  95. uncountable/types/client_config_t.py +10 -0
  96. uncountable/types/entity_t.py +9 -1
  97. uncountable/types/exports_t.py +1 -0
  98. uncountable/types/integration_server_t.py +2 -0
  99. uncountable/types/integration_session.py +10 -0
  100. uncountable/types/integration_session_t.py +60 -0
  101. uncountable/types/integrations.py +10 -0
  102. uncountable/types/integrations_t.py +62 -0
  103. uncountable/types/listing.py +46 -0
  104. uncountable/types/listing_t.py +533 -0
  105. uncountable/types/notices.py +8 -0
  106. uncountable/types/notices_t.py +37 -0
  107. uncountable/types/notifications.py +11 -0
  108. uncountable/types/notifications_t.py +74 -0
  109. uncountable/types/queued_job.py +2 -0
  110. uncountable/types/queued_job_t.py +20 -2
  111. uncountable/types/sockets.py +20 -0
  112. uncountable/types/sockets_t.py +169 -0
  113. uncountable/types/uploader.py +24 -0
  114. uncountable/types/uploader_t.py +222 -0
  115. {uncountablepythonsdk-0.0.115.dist-info → uncountablepythonsdk-0.0.142.dev0.dist-info}/METADATA +5 -2
  116. {uncountablepythonsdk-0.0.115.dist-info → uncountablepythonsdk-0.0.142.dev0.dist-info}/RECORD +118 -79
  117. docs/quickstart.md +0 -19
  118. {uncountablepythonsdk-0.0.115.dist-info → uncountablepythonsdk-0.0.142.dev0.dist-info}/WHEEL +0 -0
  119. {uncountablepythonsdk-0.0.115.dist-info → uncountablepythonsdk-0.0.142.dev0.dist-info}/top_level.txt +0 -0
@@ -21,6 +21,7 @@ __all__: list[str] = [
21
21
  "FileDownloadQuery",
22
22
  "FileDownloadQueryBase",
23
23
  "FileDownloadQueryEntityField",
24
+ "FileDownloadQueryTextDocumentId",
24
25
  "FileDownloadQueryType",
25
26
  ]
26
27
 
@@ -31,6 +32,7 @@ ENDPOINT_PATH = "api/external/files/download_file"
31
32
  # DO NOT MODIFY -- This file is generated by type_spec
32
33
  class FileDownloadQueryType(StrEnum):
33
34
  ENTITY_FIELD = "entity_field"
35
+ TEXT_DOCUMENT_ID = "text_document_id"
34
36
 
35
37
 
36
38
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -54,14 +56,26 @@ class FileDownloadQueryEntityField(FileDownloadQueryBase):
54
56
  field_key: identifier_t.IdentifierKey
55
57
 
56
58
 
59
+ # DO NOT MODIFY -- This file is generated by type_spec
60
+ @serial_class(
61
+ named_type_path="sdk.api.files.download_file.FileDownloadQueryTextDocumentId",
62
+ parse_require={"type"},
63
+ )
64
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
65
+ class FileDownloadQueryTextDocumentId(FileDownloadQueryBase):
66
+ type: typing.Literal[FileDownloadQueryType.TEXT_DOCUMENT_ID] = FileDownloadQueryType.TEXT_DOCUMENT_ID
67
+ text_document_id: base_t.ObjectId
68
+
69
+
57
70
  # DO NOT MODIFY -- This file is generated by type_spec
58
71
  FileDownloadQuery = typing.Annotated[
59
- typing.Union[FileDownloadQueryEntityField],
72
+ FileDownloadQueryEntityField | FileDownloadQueryTextDocumentId,
60
73
  serial_union_annotation(
61
74
  named_type_path="sdk.api.files.download_file.FileDownloadQuery",
62
75
  discriminator="type",
63
76
  discriminator_map={
64
77
  "entity_field": FileDownloadQueryEntityField,
78
+ "text_document_id": FileDownloadQueryTextDocumentId,
65
79
  },
66
80
  ),
67
81
  ]
@@ -0,0 +1 @@
1
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -0,0 +1,41 @@
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 base_t
12
+ from ... import integrations_t
13
+
14
+ __all__: list[str] = [
15
+ "Arguments",
16
+ "Data",
17
+ "ENDPOINT_METHOD",
18
+ "ENDPOINT_PATH",
19
+ ]
20
+
21
+ ENDPOINT_METHOD = "POST"
22
+ ENDPOINT_PATH = "api/external/integrations/publish_realtime_data"
23
+
24
+
25
+ # DO NOT MODIFY -- This file is generated by type_spec
26
+ @serial_class(
27
+ named_type_path="sdk.api.integrations.publish_realtime_data.Arguments",
28
+ )
29
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
30
+ class Arguments:
31
+ data_package: integrations_t.DataPackage
32
+
33
+
34
+ # DO NOT MODIFY -- This file is generated by type_spec
35
+ @serial_class(
36
+ named_type_path="sdk.api.integrations.publish_realtime_data.Data",
37
+ )
38
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
39
+ class Data:
40
+ pass
41
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -0,0 +1,49 @@
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 entity_t
14
+ from ... import notices_t
15
+ from ... import notifications_t
16
+
17
+ __all__: list[str] = [
18
+ "Arguments",
19
+ "Data",
20
+ "ENDPOINT_METHOD",
21
+ "ENDPOINT_PATH",
22
+ ]
23
+
24
+ ENDPOINT_METHOD = "POST"
25
+ ENDPOINT_PATH = "api/external/integrations/push_notification"
26
+
27
+
28
+ # DO NOT MODIFY -- This file is generated by type_spec
29
+ @serial_class(
30
+ named_type_path="sdk.api.integrations.push_notification.Arguments",
31
+ )
32
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
33
+ class Arguments:
34
+ notification_targets: list[notifications_t.NotificationTarget]
35
+ subject: str
36
+ message: str
37
+ display_notice: bool = False
38
+ entity: entity_t.EntityIdentifier | None = None
39
+ notice_configuration: notices_t.NotificationNoticeConfiguration | None = None
40
+
41
+
42
+ # DO NOT MODIFY -- This file is generated by type_spec
43
+ @serial_class(
44
+ named_type_path="sdk.api.integrations.push_notification.Data",
45
+ )
46
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
47
+ class Data(async_batch_t.AsyncBatchActionReturn):
48
+ pass
49
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -0,0 +1,41 @@
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 base_t
12
+ from ... import sockets_t
13
+
14
+ __all__: list[str] = [
15
+ "Arguments",
16
+ "Data",
17
+ "ENDPOINT_METHOD",
18
+ "ENDPOINT_PATH",
19
+ ]
20
+
21
+ ENDPOINT_METHOD = "POST"
22
+ ENDPOINT_PATH = "api/external/integrations/register_sockets_token"
23
+
24
+
25
+ # DO NOT MODIFY -- This file is generated by type_spec
26
+ @serial_class(
27
+ named_type_path="sdk.api.integrations.register_sockets_token.Arguments",
28
+ )
29
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
30
+ class Arguments:
31
+ socket_request: sockets_t.SocketTokenRequest
32
+
33
+
34
+ # DO NOT MODIFY -- This file is generated by type_spec
35
+ @serial_class(
36
+ named_type_path="sdk.api.integrations.register_sockets_token.Data",
37
+ )
38
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
39
+ class Data:
40
+ response: sockets_t.SocketTokenResponse
41
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -0,0 +1 @@
1
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -0,0 +1,57 @@
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 base_t
12
+ from ... import entity_t
13
+ from ... import listing_t
14
+
15
+ __all__: list[str] = [
16
+ "Arguments",
17
+ "Data",
18
+ "ENDPOINT_METHOD",
19
+ "ENDPOINT_PATH",
20
+ "ListingRow",
21
+ ]
22
+
23
+ ENDPOINT_METHOD = "POST"
24
+ ENDPOINT_PATH = "api/external/listing/fetch_listing"
25
+
26
+
27
+ # DO NOT MODIFY -- This file is generated by type_spec
28
+ @serial_class(
29
+ named_type_path="sdk.api.listing.fetch_listing.Arguments",
30
+ )
31
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
32
+ class Arguments:
33
+ entity_type: entity_t.EntityType
34
+ columns: list[listing_t.ColumnIdentifier]
35
+ filters: listing_t.FilterNode | None = None
36
+ limit: int | None = None
37
+ offset: int | None = None
38
+
39
+
40
+ # DO NOT MODIFY -- This file is generated by type_spec
41
+ @serial_class(
42
+ named_type_path="sdk.api.listing.fetch_listing.ListingRow",
43
+ unconverted_values={"column_values"},
44
+ )
45
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
46
+ class ListingRow:
47
+ column_values: list[base_t.JsonValue]
48
+
49
+
50
+ # DO NOT MODIFY -- This file is generated by type_spec
51
+ @serial_class(
52
+ named_type_path="sdk.api.listing.fetch_listing.Data",
53
+ )
54
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
55
+ class Data:
56
+ results: list[ListingRow]
57
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -0,0 +1 @@
1
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -0,0 +1,119 @@
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 pkgs.serialization import serial_union_annotation
13
+ from pkgs.serialization import serial_string_enum
14
+ from ... import base_t
15
+ from ... import identifier_t
16
+
17
+ __all__: list[str] = [
18
+ "Arguments",
19
+ "Data",
20
+ "ENDPOINT_METHOD",
21
+ "ENDPOINT_PATH",
22
+ "InputContent",
23
+ "InputContentTextMarkdown",
24
+ "InputContentType",
25
+ "Location",
26
+ "LocationAppendToFirstPage",
27
+ "LocationType",
28
+ ]
29
+
30
+ ENDPOINT_METHOD = "POST"
31
+ ENDPOINT_PATH = "api/external/notebooks/add_notebook_content"
32
+
33
+
34
+ # DO NOT MODIFY -- This file is generated by type_spec
35
+ @serial_string_enum(
36
+ labels={
37
+ "append_to_first_page": "Append To First Page",
38
+ },
39
+ )
40
+ class LocationType(StrEnum):
41
+ APPEND_TO_FIRST_PAGE = "append_to_first_page"
42
+
43
+
44
+ # DO NOT MODIFY -- This file is generated by type_spec
45
+ @serial_class(
46
+ named_type_path="sdk.api.notebooks.add_notebook_content.LocationAppendToFirstPage",
47
+ parse_require={"type"},
48
+ )
49
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
50
+ class LocationAppendToFirstPage:
51
+ type: typing.Literal[LocationType.APPEND_TO_FIRST_PAGE] = LocationType.APPEND_TO_FIRST_PAGE
52
+
53
+
54
+ # DO NOT MODIFY -- This file is generated by type_spec
55
+ Location = typing.Annotated[
56
+ typing.Union[LocationAppendToFirstPage],
57
+ serial_union_annotation(
58
+ named_type_path="sdk.api.notebooks.add_notebook_content.Location",
59
+ discriminator="type",
60
+ discriminator_map={
61
+ "append_to_first_page": LocationAppendToFirstPage,
62
+ },
63
+ ),
64
+ ]
65
+
66
+
67
+ # DO NOT MODIFY -- This file is generated by type_spec
68
+ @serial_string_enum(
69
+ labels={
70
+ "text_markdown": "Text Markdown",
71
+ },
72
+ )
73
+ class InputContentType(StrEnum):
74
+ TEXT_MARKDOWN = "text_markdown"
75
+
76
+
77
+ # DO NOT MODIFY -- This file is generated by type_spec
78
+ @serial_class(
79
+ named_type_path="sdk.api.notebooks.add_notebook_content.InputContentTextMarkdown",
80
+ parse_require={"type"},
81
+ )
82
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
83
+ class InputContentTextMarkdown:
84
+ type: typing.Literal[InputContentType.TEXT_MARKDOWN] = InputContentType.TEXT_MARKDOWN
85
+ text_markdown: str
86
+
87
+
88
+ # DO NOT MODIFY -- This file is generated by type_spec
89
+ InputContent = typing.Annotated[
90
+ typing.Union[InputContentTextMarkdown],
91
+ serial_union_annotation(
92
+ named_type_path="sdk.api.notebooks.add_notebook_content.InputContent",
93
+ discriminator="type",
94
+ discriminator_map={
95
+ "text_markdown": InputContentTextMarkdown,
96
+ },
97
+ ),
98
+ ]
99
+
100
+
101
+ # DO NOT MODIFY -- This file is generated by type_spec
102
+ @serial_class(
103
+ named_type_path="sdk.api.notebooks.add_notebook_content.Arguments",
104
+ )
105
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
106
+ class Arguments:
107
+ notebook_key: identifier_t.IdentifierKey
108
+ location: Location
109
+ contents: list[InputContent]
110
+
111
+
112
+ # DO NOT MODIFY -- This file is generated by type_spec
113
+ @serial_class(
114
+ named_type_path="sdk.api.notebooks.add_notebook_content.Data",
115
+ )
116
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
117
+ class Data:
118
+ pass
119
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -0,0 +1,173 @@
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 pkgs.serialization import serial_union_annotation
13
+ from pkgs.serialization import serial_alias_annotation
14
+ from ... import base_t
15
+
16
+ __all__: list[str] = [
17
+ "Arguments",
18
+ "Data",
19
+ "ENDPOINT_METHOD",
20
+ "ENDPOINT_PATH",
21
+ "OrganizationParameter",
22
+ "OrganizationParameterBase",
23
+ "OrganizationParameterCategory",
24
+ "OrganizationParameterConditionParameter",
25
+ "OrganizationParameterRecipeInput",
26
+ "OrganizationParameterType",
27
+ "OutputOrganizationRequest",
28
+ "OutputOrganizationRequestMaterialFamily",
29
+ "OutputOrganizationRequestProject",
30
+ "OutputOrganizationRequestScope",
31
+ "OutputOrganizationRequestUser",
32
+ ]
33
+
34
+ ENDPOINT_METHOD = "GET"
35
+ ENDPOINT_PATH = "api/external/outputs/get_output_organization"
36
+
37
+
38
+ # DO NOT MODIFY -- This file is generated by type_spec
39
+ class OutputOrganizationRequestScope(StrEnum):
40
+ MATERIAL_FAMILY = "material_family"
41
+ PROJECT = "project"
42
+ USER = "user"
43
+
44
+
45
+ # DO NOT MODIFY -- This file is generated by type_spec
46
+ @serial_class(
47
+ named_type_path="sdk.api.outputs.get_output_organization.OutputOrganizationRequestMaterialFamily",
48
+ parse_require={"scope"},
49
+ )
50
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
51
+ class OutputOrganizationRequestMaterialFamily:
52
+ scope: typing.Literal[OutputOrganizationRequestScope.MATERIAL_FAMILY] = OutputOrganizationRequestScope.MATERIAL_FAMILY
53
+ material_family_id: base_t.ObjectId
54
+
55
+
56
+ # DO NOT MODIFY -- This file is generated by type_spec
57
+ @serial_class(
58
+ named_type_path="sdk.api.outputs.get_output_organization.OutputOrganizationRequestProject",
59
+ parse_require={"scope"},
60
+ )
61
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
62
+ class OutputOrganizationRequestProject:
63
+ scope: typing.Literal[OutputOrganizationRequestScope.PROJECT] = OutputOrganizationRequestScope.PROJECT
64
+ project_id: base_t.ObjectId
65
+
66
+
67
+ # DO NOT MODIFY -- This file is generated by type_spec
68
+ @serial_class(
69
+ named_type_path="sdk.api.outputs.get_output_organization.OutputOrganizationRequestUser",
70
+ parse_require={"scope"},
71
+ )
72
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
73
+ class OutputOrganizationRequestUser:
74
+ scope: typing.Literal[OutputOrganizationRequestScope.USER] = OutputOrganizationRequestScope.USER
75
+ material_family_id: base_t.ObjectId
76
+ user_id: base_t.ObjectId
77
+ project_id: base_t.ObjectId | None = None
78
+
79
+
80
+ # DO NOT MODIFY -- This file is generated by type_spec
81
+ OutputOrganizationRequest = typing.Annotated[
82
+ OutputOrganizationRequestMaterialFamily | OutputOrganizationRequestProject | OutputOrganizationRequestUser,
83
+ serial_alias_annotation(
84
+ named_type_path="sdk.api.outputs.get_output_organization.OutputOrganizationRequest",
85
+ ),
86
+ ]
87
+
88
+
89
+ # DO NOT MODIFY -- This file is generated by type_spec
90
+ @serial_class(
91
+ named_type_path="sdk.api.outputs.get_output_organization.Arguments",
92
+ )
93
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
94
+ class Arguments:
95
+ request: OutputOrganizationRequest
96
+
97
+
98
+ # DO NOT MODIFY -- This file is generated by type_spec
99
+ class OrganizationParameterType(StrEnum):
100
+ CATEGORY = "category"
101
+ RECIPE_INPUT = "recipe_input"
102
+ CONDITION_PARAMETER = "condition_parameter"
103
+
104
+
105
+ # DO NOT MODIFY -- This file is generated by type_spec
106
+ @serial_class(
107
+ named_type_path="sdk.api.outputs.get_output_organization.OrganizationParameterBase",
108
+ )
109
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
110
+ class OrganizationParameterBase:
111
+ output_organization_parameter_id: base_t.ObjectId
112
+ null_on_top: bool
113
+ sort_asc: bool
114
+ type: OrganizationParameterType
115
+
116
+
117
+ # DO NOT MODIFY -- This file is generated by type_spec
118
+ @serial_class(
119
+ named_type_path="sdk.api.outputs.get_output_organization.OrganizationParameterCategory",
120
+ parse_require={"type"},
121
+ )
122
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
123
+ class OrganizationParameterCategory(OrganizationParameterBase):
124
+ type: typing.Literal[OrganizationParameterType.CATEGORY] = OrganizationParameterType.CATEGORY
125
+
126
+
127
+ # DO NOT MODIFY -- This file is generated by type_spec
128
+ @serial_class(
129
+ named_type_path="sdk.api.outputs.get_output_organization.OrganizationParameterRecipeInput",
130
+ parse_require={"type"},
131
+ )
132
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
133
+ class OrganizationParameterRecipeInput(OrganizationParameterBase):
134
+ input_id: base_t.ObjectId
135
+ type: typing.Literal[OrganizationParameterType.RECIPE_INPUT] = OrganizationParameterType.RECIPE_INPUT
136
+
137
+
138
+ # DO NOT MODIFY -- This file is generated by type_spec
139
+ @serial_class(
140
+ named_type_path="sdk.api.outputs.get_output_organization.OrganizationParameterConditionParameter",
141
+ parse_require={"type"},
142
+ )
143
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
144
+ class OrganizationParameterConditionParameter(OrganizationParameterBase):
145
+ condition_parameter_id: base_t.ObjectId
146
+ type: typing.Literal[OrganizationParameterType.CONDITION_PARAMETER] = OrganizationParameterType.CONDITION_PARAMETER
147
+
148
+
149
+ # DO NOT MODIFY -- This file is generated by type_spec
150
+ OrganizationParameter = typing.Annotated[
151
+ OrganizationParameterCategory | OrganizationParameterRecipeInput | OrganizationParameterConditionParameter,
152
+ serial_union_annotation(
153
+ named_type_path="sdk.api.outputs.get_output_organization.OrganizationParameter",
154
+ discriminator="type",
155
+ discriminator_map={
156
+ "category": OrganizationParameterCategory,
157
+ "recipe_input": OrganizationParameterRecipeInput,
158
+ "condition_parameter": OrganizationParameterConditionParameter,
159
+ },
160
+ ),
161
+ ]
162
+
163
+
164
+ # DO NOT MODIFY -- This file is generated by type_spec
165
+ @serial_class(
166
+ named_type_path="sdk.api.outputs.get_output_organization.Data",
167
+ )
168
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
169
+ class Data:
170
+ organization_id: base_t.ObjectId | None
171
+ column_definitions: list[OrganizationParameter]
172
+ table_definitions: list[OrganizationParameter]
173
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -93,7 +93,7 @@ class RecipeInputEditClearInputs(RecipeInputEditBase):
93
93
  @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
94
94
  class RecipeInputEditInputBase(RecipeInputEditBase):
95
95
  ingredient_key: identifier_t.IdentifierKey
96
- quantity_basis: recipe_inputs_t.QuantityBasis = recipe_inputs_t.QuantityBasis.MASS
96
+ quantity_basis: recipe_inputs_t.QuantityBasis | None = recipe_inputs_t.QuantityBasis.MASS
97
97
  input_value_type: recipe_inputs_t.InputValueType = recipe_inputs_t.InputValueType.VALUE
98
98
  value_numeric: Decimal | None = None
99
99
  value_str: str | None = None
@@ -42,8 +42,8 @@ class Arguments:
42
42
  class RecipeOutputMetadata:
43
43
  recipe_output_id: base_t.ObjectId
44
44
  recipe_output_metadata_field_id: base_t.ObjectId
45
- quantity_dec: Decimal
46
- quantity_json: base_t.JsonValue
45
+ quantity_dec: Decimal | None = None
46
+ quantity_json: base_t.JsonValue | None = None
47
47
 
48
48
 
49
49
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -6,8 +6,10 @@ from __future__ import annotations
6
6
  import typing # noqa: F401
7
7
  import datetime # noqa: F401
8
8
  from decimal import Decimal # noqa: F401
9
+ from enum import StrEnum
9
10
  import dataclasses
10
11
  from pkgs.serialization import serial_class
12
+ from pkgs.serialization import serial_string_enum
11
13
  from ... import base_t
12
14
  from ... import experiment_groups_t
13
15
  from ... import inputs_t
@@ -24,7 +26,9 @@ __all__: list[str] = [
24
26
  "ENDPOINT_PATH",
25
27
  "Recipe",
26
28
  "RecipeInput",
29
+ "RecipeLockStatus",
27
30
  "RecipeOutput",
31
+ "RecipeOutputInclusion",
28
32
  "RecipeStep",
29
33
  "RecipeStepGroup",
30
34
  "RecipeStepRelationship",
@@ -46,6 +50,19 @@ class Arguments:
46
50
  project_id: base_t.ObjectId | None = None
47
51
  offset: int | None = None
48
52
  limit: int | None = None
53
+ empty_output_behavior: RecipeOutputInclusion | None = None
54
+
55
+
56
+ # DO NOT MODIFY -- This file is generated by type_spec
57
+ @serial_string_enum(
58
+ labels={
59
+ "include_null": "Include Outputs without values",
60
+ "exclude_null": "Exclude Outputs without values",
61
+ },
62
+ )
63
+ class RecipeOutputInclusion(StrEnum):
64
+ INCLUDE_NULL = "include_null"
65
+ EXCLUDE_NULL = "exclude_null"
49
66
 
50
67
 
51
68
  # DO NOT MODIFY -- This file is generated by type_spec
@@ -138,6 +155,7 @@ class RecipeStepGroup:
138
155
  )
139
156
  @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
140
157
  class RecipeWorkflowStep:
158
+ recipe_workflow_step_name: str | None
141
159
  recipe_workflow_step_id: base_t.ObjectId
142
160
  workflow_step_id: base_t.ObjectId
143
161
  recipe_step_groups: list[RecipeStepGroup]
@@ -158,6 +176,16 @@ class RecipeStepRelationship:
158
176
  actual_quantity_dec: Decimal | None = None
159
177
 
160
178
 
179
+ # DO NOT MODIFY -- This file is generated by type_spec
180
+ @serial_class(
181
+ named_type_path="sdk.api.recipes.get_recipes_data.RecipeLockStatus",
182
+ )
183
+ @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
184
+ class RecipeLockStatus:
185
+ has_locked_inputs: bool
186
+ has_locked_outputs: bool
187
+
188
+
161
189
  # DO NOT MODIFY -- This file is generated by type_spec
162
190
  @serial_class(
163
191
  named_type_path="sdk.api.recipes.get_recipes_data.Recipe",
@@ -177,6 +205,7 @@ class Recipe:
177
205
  tag_ids: list[base_t.ObjectId]
178
206
  experiment_group_ids: list[base_t.ObjectId]
179
207
  step_relationships: list[RecipeStepRelationship]
208
+ recipe_lock_status: RecipeLockStatus
180
209
  creating_user_id: base_t.ObjectId | None = None
181
210
  barcode_value: str | None = None
182
211
 
@@ -9,6 +9,7 @@ from decimal import Decimal # noqa: F401
9
9
  from enum import StrEnum
10
10
  import dataclasses
11
11
  from pkgs.serialization import serial_class
12
+ from ... import async_batch_t
12
13
  from ... import base_t
13
14
  from ... import identifier_t
14
15
 
@@ -58,6 +59,6 @@ class Arguments:
58
59
  named_type_path="sdk.api.recipes.lock_recipes.Data",
59
60
  )
60
61
  @dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
61
- class Data:
62
+ class Data(async_batch_t.AsyncBatchActionReturn):
62
63
  pass
63
64
  # DO NOT MODIFY -- This file is generated by type_spec