UncountablePythonSDK 0.0.123__py3-none-any.whl → 0.0.124__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.
- docs/conf.py +22 -3
- docs/index.md +1 -1
- docs/requirements.txt +1 -1
- examples/integration-server/pyproject.toml +1 -1
- uncountable/integration/http_server/types.py +3 -1
- uncountable/integration/scheduler.py +62 -17
- uncountable/integration/telemetry.py +2 -1
- uncountable/types/__init__.py +6 -0
- uncountable/types/api/integrations/push_notification.py +47 -0
- uncountable/types/api/outputs/get_output_organization.py +173 -0
- uncountable/types/async_batch_processor.py +41 -0
- uncountable/types/async_batch_t.py +1 -0
- uncountable/types/client_base.py +28 -0
- uncountable/types/notifications.py +11 -0
- uncountable/types/notifications_t.py +74 -0
- {uncountablepythonsdk-0.0.123.dist-info → uncountablepythonsdk-0.0.124.dist-info}/METADATA +2 -2
- {uncountablepythonsdk-0.0.123.dist-info → uncountablepythonsdk-0.0.124.dist-info}/RECORD +19 -15
- {uncountablepythonsdk-0.0.123.dist-info → uncountablepythonsdk-0.0.124.dist-info}/WHEEL +0 -0
- {uncountablepythonsdk-0.0.123.dist-info → uncountablepythonsdk-0.0.124.dist-info}/top_level.txt +0 -0
docs/conf.py
CHANGED
|
@@ -70,14 +70,33 @@ def _hook_missing_reference(
|
|
|
70
70
|
Manually resolve reference when autoapi reference resolution fails.
|
|
71
71
|
This is necessary because autoapi does not fully support type aliases.
|
|
72
72
|
"""
|
|
73
|
+
# example reftarget value: uncountable.types.identifier_t.IdentifierKey
|
|
73
74
|
target = node.get("reftarget", "")
|
|
75
|
+
|
|
76
|
+
# example refdoc value: api/uncountable/types/generic_upload_t/GenericUploadStrategy
|
|
77
|
+
current_doc = node.get("refdoc", "")
|
|
78
|
+
|
|
74
79
|
if not target.startswith("uncountable"):
|
|
75
80
|
return None
|
|
76
|
-
|
|
81
|
+
|
|
82
|
+
target_module, target_name = target.rsplit(".", 1)
|
|
83
|
+
|
|
84
|
+
# construct relative path from current doc page to target page
|
|
85
|
+
relative_segments_to_root = [".." for _ in current_doc.split("/")]
|
|
86
|
+
relative_segments_to_target = target_module.split(".")
|
|
87
|
+
|
|
88
|
+
# example full relative path: ../../../../../api/uncountable/types/identifier_t/#uncountable.types.identifier_t.IdentifierKey
|
|
89
|
+
full_relative_path = "/".join([
|
|
90
|
+
*relative_segments_to_root,
|
|
91
|
+
autoapi_root,
|
|
92
|
+
*relative_segments_to_target,
|
|
93
|
+
f"#{target}",
|
|
94
|
+
])
|
|
95
|
+
|
|
77
96
|
return nodes.reference(
|
|
78
|
-
text=
|
|
97
|
+
text=target_name if python_use_unqualified_type_names else target,
|
|
79
98
|
children=[contnode],
|
|
80
|
-
refuri=
|
|
99
|
+
refuri=full_relative_path,
|
|
81
100
|
)
|
|
82
101
|
|
|
83
102
|
|
docs/index.md
CHANGED
|
@@ -112,5 +112,5 @@ def fetch_all_projects(client: Client) -> list[IdName]:
|
|
|
112
112
|
Overview <self>
|
|
113
113
|
Available SDK Methods <api/uncountable/core/client/Client>
|
|
114
114
|
integration_examples/index
|
|
115
|
-
SDK Reference <
|
|
115
|
+
SDK Reference <api/uncountable/index>
|
|
116
116
|
```
|
docs/requirements.txt
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
import functools
|
|
3
|
+
import json
|
|
3
4
|
from dataclasses import dataclass
|
|
4
5
|
|
|
5
6
|
from flask.wrappers import Response
|
|
@@ -42,7 +43,8 @@ class HttpException(Exception):
|
|
|
42
43
|
|
|
43
44
|
def make_error_response(self) -> Response:
|
|
44
45
|
return Response(
|
|
45
|
-
status=self.error_code,
|
|
46
|
+
status=self.error_code,
|
|
47
|
+
response=json.dumps({"error": {"message": str(self)}}),
|
|
46
48
|
)
|
|
47
49
|
|
|
48
50
|
|
|
@@ -5,6 +5,7 @@ import sys
|
|
|
5
5
|
import time
|
|
6
6
|
from dataclasses import dataclass
|
|
7
7
|
from datetime import UTC
|
|
8
|
+
from enum import StrEnum
|
|
8
9
|
|
|
9
10
|
from opentelemetry.trace import get_current_span
|
|
10
11
|
|
|
@@ -19,11 +20,19 @@ from uncountable.integration.telemetry import Logger
|
|
|
19
20
|
|
|
20
21
|
SHUTDOWN_TIMEOUT_SECS = 30
|
|
21
22
|
|
|
23
|
+
AnyProcess = multiprocessing.Process | subprocess.Popen[bytes]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ProcessName(StrEnum):
|
|
27
|
+
QUEUE_RUNNER = "queue_runner"
|
|
28
|
+
CRON_SERVER = "cron_server"
|
|
29
|
+
UWSGI = "uwsgi"
|
|
30
|
+
|
|
22
31
|
|
|
23
32
|
@dataclass(kw_only=True)
|
|
24
33
|
class ProcessInfo:
|
|
25
|
-
name:
|
|
26
|
-
process:
|
|
34
|
+
name: ProcessName
|
|
35
|
+
process: AnyProcess
|
|
27
36
|
|
|
28
37
|
@property
|
|
29
38
|
def is_alive(self) -> bool:
|
|
@@ -46,14 +55,14 @@ class ProcessInfo:
|
|
|
46
55
|
return self.process.poll()
|
|
47
56
|
|
|
48
57
|
|
|
49
|
-
def handle_shutdown(logger: Logger, processes:
|
|
58
|
+
def handle_shutdown(logger: Logger, processes: dict[ProcessName, ProcessInfo]) -> None:
|
|
50
59
|
logger.log_info("received shutdown command, shutting down sub-processes")
|
|
51
|
-
for proc_info in processes:
|
|
60
|
+
for proc_info in processes.values():
|
|
52
61
|
if proc_info.is_alive:
|
|
53
62
|
proc_info.process.terminate()
|
|
54
63
|
|
|
55
64
|
shutdown_start = time.time()
|
|
56
|
-
still_living_processes = processes
|
|
65
|
+
still_living_processes = list(processes.values())
|
|
57
66
|
while (
|
|
58
67
|
time.time() - shutdown_start < SHUTDOWN_TIMEOUT_SECS
|
|
59
68
|
and len(still_living_processes) > 0
|
|
@@ -82,14 +91,50 @@ def handle_shutdown(logger: Logger, processes: list[ProcessInfo]) -> None:
|
|
|
82
91
|
proc_info.process.kill()
|
|
83
92
|
|
|
84
93
|
|
|
85
|
-
def
|
|
86
|
-
|
|
94
|
+
def restart_process(
|
|
95
|
+
logger: Logger, proc_info: ProcessInfo, processes: dict[ProcessName, ProcessInfo]
|
|
96
|
+
) -> None:
|
|
97
|
+
logger.log_error(
|
|
98
|
+
f"process {proc_info.name} shut down unexpectedly - exit code {proc_info.exitcode}. Restarting..."
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
match proc_info.name:
|
|
102
|
+
case ProcessName.QUEUE_RUNNER:
|
|
103
|
+
queue_proc = multiprocessing.Process(target=start_queue_runner)
|
|
104
|
+
queue_proc.start()
|
|
105
|
+
new_info = ProcessInfo(name=ProcessName.QUEUE_RUNNER, process=queue_proc)
|
|
106
|
+
processes[ProcessName.QUEUE_RUNNER] = new_info
|
|
107
|
+
try:
|
|
108
|
+
_wait_queue_runner_online()
|
|
109
|
+
logger.log_info("queue runner restarted successfully")
|
|
110
|
+
except Exception as e:
|
|
111
|
+
logger.log_exception(e)
|
|
112
|
+
logger.log_error(
|
|
113
|
+
"queue runner failed to restart, shutting down scheduler"
|
|
114
|
+
)
|
|
115
|
+
handle_shutdown(logger, processes)
|
|
116
|
+
sys.exit(1)
|
|
117
|
+
|
|
118
|
+
case ProcessName.CRON_SERVER:
|
|
119
|
+
cron_proc = multiprocessing.Process(target=cron_target)
|
|
120
|
+
cron_proc.start()
|
|
121
|
+
new_info = ProcessInfo(name=ProcessName.CRON_SERVER, process=cron_proc)
|
|
122
|
+
processes[ProcessName.CRON_SERVER] = new_info
|
|
123
|
+
logger.log_info("cron server restarted successfully")
|
|
124
|
+
|
|
125
|
+
case ProcessName.UWSGI:
|
|
126
|
+
uwsgi_proc: AnyProcess = subprocess.Popen(["uwsgi", "--die-on-term"])
|
|
127
|
+
new_info = ProcessInfo(name=ProcessName.UWSGI, process=uwsgi_proc)
|
|
128
|
+
processes[ProcessName.UWSGI] = new_info
|
|
129
|
+
logger.log_info("uwsgi restarted successfully")
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def check_process_alive(
|
|
133
|
+
logger: Logger, processes: dict[ProcessName, ProcessInfo]
|
|
134
|
+
) -> None:
|
|
135
|
+
for proc_info in processes.values():
|
|
87
136
|
if not proc_info.is_alive:
|
|
88
|
-
logger
|
|
89
|
-
f"process {proc_info.name} shut down unexpectedly! shutting down scheduler; exit code is {proc_info.exitcode}"
|
|
90
|
-
)
|
|
91
|
-
handle_shutdown(logger, processes)
|
|
92
|
-
sys.exit(1)
|
|
137
|
+
restart_process(logger, proc_info, processes)
|
|
93
138
|
|
|
94
139
|
|
|
95
140
|
def _wait_queue_runner_online() -> None:
|
|
@@ -113,17 +158,17 @@ def _wait_queue_runner_online() -> None:
|
|
|
113
158
|
|
|
114
159
|
def main() -> None:
|
|
115
160
|
logger = Logger(get_current_span())
|
|
116
|
-
processes:
|
|
161
|
+
processes: dict[ProcessName, ProcessInfo] = {}
|
|
117
162
|
|
|
118
163
|
multiprocessing.set_start_method("forkserver")
|
|
119
164
|
|
|
120
165
|
def add_process(process: ProcessInfo) -> None:
|
|
121
|
-
processes.
|
|
166
|
+
processes[process.name] = process
|
|
122
167
|
logger.log_info(f"started process {process.name}")
|
|
123
168
|
|
|
124
169
|
runner_process = multiprocessing.Process(target=start_queue_runner)
|
|
125
170
|
runner_process.start()
|
|
126
|
-
add_process(ProcessInfo(name=
|
|
171
|
+
add_process(ProcessInfo(name=ProcessName.QUEUE_RUNNER, process=runner_process))
|
|
127
172
|
|
|
128
173
|
try:
|
|
129
174
|
_wait_queue_runner_online()
|
|
@@ -134,13 +179,13 @@ def main() -> None:
|
|
|
134
179
|
|
|
135
180
|
cron_process = multiprocessing.Process(target=cron_target)
|
|
136
181
|
cron_process.start()
|
|
137
|
-
add_process(ProcessInfo(name=
|
|
182
|
+
add_process(ProcessInfo(name=ProcessName.CRON_SERVER, process=cron_process))
|
|
138
183
|
|
|
139
184
|
uwsgi_process = subprocess.Popen([
|
|
140
185
|
"uwsgi",
|
|
141
186
|
"--die-on-term",
|
|
142
187
|
])
|
|
143
|
-
add_process(ProcessInfo(name=
|
|
188
|
+
add_process(ProcessInfo(name=ProcessName.UWSGI, process=uwsgi_process))
|
|
144
189
|
|
|
145
190
|
try:
|
|
146
191
|
while True:
|
|
@@ -34,7 +34,8 @@ def _cast_attributes(attributes: dict[str, base_t.JsonValue]) -> Attributes:
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def one_line_formatter(record: LogRecord) -> str:
|
|
37
|
-
|
|
37
|
+
json_data = record.to_json()
|
|
38
|
+
return json.dumps(json.loads(json_data), separators=(",", ":")) + "\n"
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
@functools.cache
|
uncountable/types/__init__.py
CHANGED
|
@@ -50,6 +50,7 @@ from .api.inputs import get_input_names as get_input_names_t
|
|
|
50
50
|
from .api.inputs import get_inputs_data as get_inputs_data_t
|
|
51
51
|
from .api.outputs import get_output_data as get_output_data_t
|
|
52
52
|
from .api.outputs import get_output_names as get_output_names_t
|
|
53
|
+
from .api.outputs import get_output_organization as get_output_organization_t
|
|
53
54
|
from .api.project import get_projects as get_projects_t
|
|
54
55
|
from .api.project import get_projects_data as get_projects_data_t
|
|
55
56
|
from .api.recipes import get_recipe_calculations as get_recipe_calculations_t
|
|
@@ -74,12 +75,14 @@ from .api.entity import lock_entity as lock_entity_t
|
|
|
74
75
|
from .api.recipes import lock_recipes as lock_recipes_t
|
|
75
76
|
from .api.entity import lookup_entity as lookup_entity_t
|
|
76
77
|
from .api.id_source import match_id_source as match_id_source_t
|
|
78
|
+
from . import notifications_t as notifications_t
|
|
77
79
|
from . import outputs_t as outputs_t
|
|
78
80
|
from . import overrides_t as overrides_t
|
|
79
81
|
from . import permissions_t as permissions_t
|
|
80
82
|
from . import phases_t as phases_t
|
|
81
83
|
from . import post_base_t as post_base_t
|
|
82
84
|
from .api.integrations import publish_realtime_data as publish_realtime_data_t
|
|
85
|
+
from .api.integrations import push_notification as push_notification_t
|
|
83
86
|
from . import queued_job_t as queued_job_t
|
|
84
87
|
from . import recipe_identifiers_t as recipe_identifiers_t
|
|
85
88
|
from . import recipe_inputs_t as recipe_inputs_t
|
|
@@ -172,6 +175,7 @@ __all__: list[str] = [
|
|
|
172
175
|
"get_inputs_data_t",
|
|
173
176
|
"get_output_data_t",
|
|
174
177
|
"get_output_names_t",
|
|
178
|
+
"get_output_organization_t",
|
|
175
179
|
"get_projects_t",
|
|
176
180
|
"get_projects_data_t",
|
|
177
181
|
"get_recipe_calculations_t",
|
|
@@ -196,12 +200,14 @@ __all__: list[str] = [
|
|
|
196
200
|
"lock_recipes_t",
|
|
197
201
|
"lookup_entity_t",
|
|
198
202
|
"match_id_source_t",
|
|
203
|
+
"notifications_t",
|
|
199
204
|
"outputs_t",
|
|
200
205
|
"overrides_t",
|
|
201
206
|
"permissions_t",
|
|
202
207
|
"phases_t",
|
|
203
208
|
"post_base_t",
|
|
204
209
|
"publish_realtime_data_t",
|
|
210
|
+
"push_notification_t",
|
|
205
211
|
"queued_job_t",
|
|
206
212
|
"recipe_identifiers_t",
|
|
207
213
|
"recipe_inputs_t",
|
|
@@ -0,0 +1,47 @@
|
|
|
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 notifications_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/integrations/push_notification"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
28
|
+
@serial_class(
|
|
29
|
+
named_type_path="sdk.api.integrations.push_notification.Arguments",
|
|
30
|
+
)
|
|
31
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
32
|
+
class Arguments:
|
|
33
|
+
notification_targets: list[notifications_t.NotificationTarget]
|
|
34
|
+
subject: str
|
|
35
|
+
message: str
|
|
36
|
+
display_notice: bool = False
|
|
37
|
+
entity: entity_t.EntityIdentifier | None = None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
41
|
+
@serial_class(
|
|
42
|
+
named_type_path="sdk.api.integrations.push_notification.Data",
|
|
43
|
+
)
|
|
44
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
45
|
+
class Data(async_batch_t.AsyncBatchActionReturn):
|
|
46
|
+
pass
|
|
47
|
+
# 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
|
|
171
|
+
column_definitions: list[OrganizationParameter]
|
|
172
|
+
table_definitions: list[OrganizationParameter]
|
|
173
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
@@ -25,6 +25,8 @@ import uncountable.types.api.entity.grant_entity_permissions as grant_entity_per
|
|
|
25
25
|
from uncountable.types import identifier_t
|
|
26
26
|
import uncountable.types.api.uploader.invoke_uploader as invoke_uploader_t
|
|
27
27
|
import uncountable.types.api.entity.lookup_entity as lookup_entity_t
|
|
28
|
+
from uncountable.types import notifications_t
|
|
29
|
+
import uncountable.types.api.integrations.push_notification as push_notification_t
|
|
28
30
|
from uncountable.types import recipe_identifiers_t
|
|
29
31
|
from uncountable.types import recipe_metadata_t
|
|
30
32
|
from uncountable.types import recipe_workflow_steps_t
|
|
@@ -492,6 +494,45 @@ class AsyncBatchProcessorBase(ABC):
|
|
|
492
494
|
batch_reference=req.batch_reference,
|
|
493
495
|
)
|
|
494
496
|
|
|
497
|
+
def push_notification(
|
|
498
|
+
self,
|
|
499
|
+
*,
|
|
500
|
+
notification_targets: list[notifications_t.NotificationTarget],
|
|
501
|
+
subject: str,
|
|
502
|
+
message: str,
|
|
503
|
+
display_notice: bool = False,
|
|
504
|
+
entity: entity_t.EntityIdentifier | None = None,
|
|
505
|
+
depends_on: list[str] | None = None,
|
|
506
|
+
) -> async_batch_t.QueuedAsyncBatchRequest:
|
|
507
|
+
"""Push a notification to a user or user group
|
|
508
|
+
|
|
509
|
+
:param depends_on: A list of batch reference keys to process before processing this request
|
|
510
|
+
"""
|
|
511
|
+
args = push_notification_t.Arguments(
|
|
512
|
+
notification_targets=notification_targets,
|
|
513
|
+
subject=subject,
|
|
514
|
+
message=message,
|
|
515
|
+
entity=entity,
|
|
516
|
+
display_notice=display_notice,
|
|
517
|
+
)
|
|
518
|
+
json_data = serialize_for_api(args)
|
|
519
|
+
|
|
520
|
+
batch_reference = str(uuid.uuid4())
|
|
521
|
+
|
|
522
|
+
req = async_batch_t.AsyncBatchRequest(
|
|
523
|
+
path=async_batch_t.AsyncBatchRequestPath.PUSH_NOTIFICATION,
|
|
524
|
+
data=json_data,
|
|
525
|
+
depends_on=depends_on,
|
|
526
|
+
batch_reference=batch_reference,
|
|
527
|
+
)
|
|
528
|
+
|
|
529
|
+
self._enqueue(req)
|
|
530
|
+
|
|
531
|
+
return async_batch_t.QueuedAsyncBatchRequest(
|
|
532
|
+
path=req.path,
|
|
533
|
+
batch_reference=req.batch_reference,
|
|
534
|
+
)
|
|
535
|
+
|
|
495
536
|
def set_entity_field_values(
|
|
496
537
|
self,
|
|
497
538
|
*,
|
|
@@ -45,6 +45,7 @@ class AsyncBatchRequestPath(StrEnum):
|
|
|
45
45
|
UPSERT_CONDITION_MATCH = "condition_parameters/upsert_condition_match"
|
|
46
46
|
COMPLETE_ASYNC_UPLOAD = "runsheet/complete_async_upload"
|
|
47
47
|
CREATE_MIX_ORDER = "recipes/create_mix_order"
|
|
48
|
+
PUSH_NOTIFICATION = "integrations/push_notification"
|
|
48
49
|
|
|
49
50
|
|
|
50
51
|
# DO NOT MODIFY -- This file is generated by type_spec
|
uncountable/types/client_base.py
CHANGED
|
@@ -64,8 +64,10 @@ import uncountable.types.api.entity.lock_entity as lock_entity_t
|
|
|
64
64
|
import uncountable.types.api.recipes.lock_recipes as lock_recipes_t
|
|
65
65
|
import uncountable.types.api.entity.lookup_entity as lookup_entity_t
|
|
66
66
|
import uncountable.types.api.id_source.match_id_source as match_id_source_t
|
|
67
|
+
from uncountable.types import notifications_t
|
|
67
68
|
from uncountable.types import permissions_t
|
|
68
69
|
from uncountable.types import post_base_t
|
|
70
|
+
import uncountable.types.api.integrations.push_notification as push_notification_t
|
|
69
71
|
from uncountable.types import recipe_identifiers_t
|
|
70
72
|
from uncountable.types import recipe_links_t
|
|
71
73
|
from uncountable.types import recipe_metadata_t
|
|
@@ -1258,6 +1260,32 @@ class ClientMethods(ABC):
|
|
|
1258
1260
|
)
|
|
1259
1261
|
return self.do_request(api_request=api_request, return_type=match_id_source_t.Data)
|
|
1260
1262
|
|
|
1263
|
+
def push_notification(
|
|
1264
|
+
self,
|
|
1265
|
+
*,
|
|
1266
|
+
notification_targets: list[notifications_t.NotificationTarget],
|
|
1267
|
+
subject: str,
|
|
1268
|
+
message: str,
|
|
1269
|
+
display_notice: bool = False,
|
|
1270
|
+
entity: entity_t.EntityIdentifier | None = None,
|
|
1271
|
+
) -> push_notification_t.Data:
|
|
1272
|
+
"""Push a notification to a user or user group
|
|
1273
|
+
|
|
1274
|
+
"""
|
|
1275
|
+
args = push_notification_t.Arguments(
|
|
1276
|
+
notification_targets=notification_targets,
|
|
1277
|
+
subject=subject,
|
|
1278
|
+
message=message,
|
|
1279
|
+
entity=entity,
|
|
1280
|
+
display_notice=display_notice,
|
|
1281
|
+
)
|
|
1282
|
+
api_request = APIRequest(
|
|
1283
|
+
method=push_notification_t.ENDPOINT_METHOD,
|
|
1284
|
+
endpoint=push_notification_t.ENDPOINT_PATH,
|
|
1285
|
+
args=args,
|
|
1286
|
+
)
|
|
1287
|
+
return self.do_request(api_request=api_request, return_type=push_notification_t.Data)
|
|
1288
|
+
|
|
1261
1289
|
def remove_recipe_from_project(
|
|
1262
1290
|
self,
|
|
1263
1291
|
*,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# ruff: noqa: E402 Q003
|
|
2
|
+
# fmt: off
|
|
3
|
+
# isort: skip_file
|
|
4
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
5
|
+
# Kept only for SDK backwards compatibility
|
|
6
|
+
from .notifications_t import NotificationTargetType as NotificationTargetType
|
|
7
|
+
from .notifications_t import NotificationTargetBase as NotificationTargetBase
|
|
8
|
+
from .notifications_t import NotificationTargetUser as NotificationTargetUser
|
|
9
|
+
from .notifications_t import NotificationTargetUserGroup as NotificationTargetUserGroup
|
|
10
|
+
from .notifications_t import NotificationTarget as NotificationTarget
|
|
11
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
@@ -0,0 +1,74 @@
|
|
|
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 . import base_t
|
|
14
|
+
from . import identifier_t
|
|
15
|
+
|
|
16
|
+
__all__: list[str] = [
|
|
17
|
+
"NotificationTarget",
|
|
18
|
+
"NotificationTargetBase",
|
|
19
|
+
"NotificationTargetType",
|
|
20
|
+
"NotificationTargetUser",
|
|
21
|
+
"NotificationTargetUserGroup",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
26
|
+
class NotificationTargetType(StrEnum):
|
|
27
|
+
USER = "user"
|
|
28
|
+
USER_GROUP = "user_group"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
32
|
+
@serial_class(
|
|
33
|
+
named_type_path="sdk.notifications.NotificationTargetBase",
|
|
34
|
+
)
|
|
35
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
36
|
+
class NotificationTargetBase:
|
|
37
|
+
type: NotificationTargetType
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
41
|
+
@serial_class(
|
|
42
|
+
named_type_path="sdk.notifications.NotificationTargetUser",
|
|
43
|
+
parse_require={"type"},
|
|
44
|
+
)
|
|
45
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
46
|
+
class NotificationTargetUser(NotificationTargetBase):
|
|
47
|
+
type: typing.Literal[NotificationTargetType.USER] = NotificationTargetType.USER
|
|
48
|
+
user_key: identifier_t.IdentifierKey
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
52
|
+
@serial_class(
|
|
53
|
+
named_type_path="sdk.notifications.NotificationTargetUserGroup",
|
|
54
|
+
parse_require={"type"},
|
|
55
|
+
)
|
|
56
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
57
|
+
class NotificationTargetUserGroup(NotificationTargetBase):
|
|
58
|
+
type: typing.Literal[NotificationTargetType.USER_GROUP] = NotificationTargetType.USER_GROUP
|
|
59
|
+
user_group_key: identifier_t.IdentifierKey
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
63
|
+
NotificationTarget = typing.Annotated[
|
|
64
|
+
NotificationTargetUser | NotificationTargetUserGroup,
|
|
65
|
+
serial_union_annotation(
|
|
66
|
+
named_type_path="sdk.notifications.NotificationTarget",
|
|
67
|
+
discriminator="type",
|
|
68
|
+
discriminator_map={
|
|
69
|
+
"user": NotificationTargetUser,
|
|
70
|
+
"user_group": NotificationTargetUserGroup,
|
|
71
|
+
},
|
|
72
|
+
),
|
|
73
|
+
]
|
|
74
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: UncountablePythonSDK
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.124
|
|
4
4
|
Summary: Uncountable SDK
|
|
5
5
|
Project-URL: Homepage, https://github.com/uncountableinc/uncountable-python-sdk
|
|
6
6
|
Project-URL: Repository, https://github.com/uncountableinc/uncountable-python-sdk.git
|
|
@@ -31,7 +31,7 @@ Requires-Dist: opentelemetry-api==1.*
|
|
|
31
31
|
Requires-Dist: opentelemetry-exporter-otlp-proto-common==1.*
|
|
32
32
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http==1.*
|
|
33
33
|
Requires-Dist: opentelemetry-sdk==1.*
|
|
34
|
-
Requires-Dist: paramiko==
|
|
34
|
+
Requires-Dist: paramiko==4.*
|
|
35
35
|
Requires-Dist: boto3==1.*
|
|
36
36
|
Requires-Dist: flask==3.*
|
|
37
37
|
Requires-Dist: simplejson==3.*
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
docs/.gitignore,sha256=_ebkZUcwfvfnGEJ95rfj1lxoBNd6EE9ZvtOc7FsbfFE,7
|
|
2
|
-
docs/conf.py,sha256=
|
|
3
|
-
docs/index.md,sha256=
|
|
2
|
+
docs/conf.py,sha256=Ky-_Y76T7pwN2aBG-dSF79Av70e7ASgcOXEdQ1qyor4,3542
|
|
3
|
+
docs/index.md,sha256=g4Yi5831fEkywYkkcFohYLkKzSI91SOZF7DxKsm9zgI,3193
|
|
4
4
|
docs/justfile,sha256=WymCEQ6W2A8Ak79iUPmecmuaUNN2htb7STUrz5K7ELE,273
|
|
5
|
-
docs/requirements.txt,sha256=
|
|
5
|
+
docs/requirements.txt,sha256=AAVxGQUFUCjyRe2gQSCD8Nezn42K_TVeEfrpIKJwmD0,171
|
|
6
6
|
docs/integration_examples/create_ingredient.md,sha256=bzTQ943YhINxa3HQylEA26rbAsjr6HvvN_HkVkrzUeA,1547
|
|
7
7
|
docs/integration_examples/create_output.md,sha256=aDn2TjzKgY-HnxnvgsZS578cvajmHpF1y2HKkHfdtd4,2104
|
|
8
8
|
docs/integration_examples/index.md,sha256=lVP6k79rGgdWPfEKM8oJvxeJsBKlpRJaZfrqn9lkiBc,73
|
|
@@ -27,7 +27,7 @@ examples/oauth.py,sha256=QUmv4c27UDs3q98yigyA_Sm3hdK5qNfnDvxh7k06ZYg,213
|
|
|
27
27
|
examples/set_recipe_metadata_file.py,sha256=cRVXGz4UN4aqnNrNSzyBmikYHpe63lMIuzOpMwD9EDU,1036
|
|
28
28
|
examples/set_recipe_output_file_sdk.py,sha256=Lz1amqppnWTX83z-C090wCJ4hcKmCD3kb-4v0uBRi0Y,782
|
|
29
29
|
examples/upload_files.py,sha256=qMaSvMSdTMPOOP55y1AwEurc0SOdZAMvEydlqJPsGpg,432
|
|
30
|
-
examples/integration-server/pyproject.toml,sha256
|
|
30
|
+
examples/integration-server/pyproject.toml,sha256=ASgrDz9wnJRSI-M_zmfGDBAPXwTgQcCHGjmhDp6CY4E,9149
|
|
31
31
|
examples/integration-server/jobs/materials_auto/concurrent_cron.py,sha256=xsK3H9ZEaniedC2nJUB0rqOcFI8y-ojfl_nLSJb9AMM,312
|
|
32
32
|
examples/integration-server/jobs/materials_auto/example_cron.py,sha256=spUMiiTEFaepbVXecjD_4aEEfqEtZGGZuWTKs9J6Xcw,736
|
|
33
33
|
examples/integration-server/jobs/materials_auto/example_http.py,sha256=eIL46ElWo8SKY7W5JWWkwZk6Qo7KRd9EJBxfy7YQ_sE,1429
|
|
@@ -111,9 +111,9 @@ uncountable/integration/cron.py,sha256=6eH-kIs3sdYPCyb62_L2M7U_uQTdMTdwY5hreEJb0
|
|
|
111
111
|
uncountable/integration/entrypoint.py,sha256=BHOYPQgKvZE6HG8Rv15MkdYl8lRkvfDgv1OdLo0oQ9Q,433
|
|
112
112
|
uncountable/integration/job.py,sha256=HFYA3YxqwyCvQLqXpMnKxp2IJUjFgjMsWVz_DTb_5eo,8229
|
|
113
113
|
uncountable/integration/scan_profiles.py,sha256=RHBmPc5E10YZzf4cmglwrn2yAy0jHBhQ-P_GlAk2TeU,2919
|
|
114
|
-
uncountable/integration/scheduler.py,sha256=
|
|
114
|
+
uncountable/integration/scheduler.py,sha256=vJQGpuMgryFp5aCQEg5BIvywnu4t3SSFcGoLfY10LKg,6610
|
|
115
115
|
uncountable/integration/server.py,sha256=lL9zmzqkQRf7V1fBT20SvIy-7ryz5hFf7DF4QX4pj1E,4699
|
|
116
|
-
uncountable/integration/telemetry.py,sha256=
|
|
116
|
+
uncountable/integration/telemetry.py,sha256=5nA_DwqLOBxDdV4cl8Ybo6I6GiJDTdqETlP5Y81SCWg,7633
|
|
117
117
|
uncountable/integration/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
118
118
|
uncountable/integration/db/connect.py,sha256=mE3bdV0huclH2iT_dXCQdRL4LkjIuf_myAR64RTWXEs,498
|
|
119
119
|
uncountable/integration/db/session.py,sha256=96cGQXpe6IugBTdSsjdP0S5yhJ6toSmbVB6qhc3FJzE,693
|
|
@@ -122,7 +122,7 @@ uncountable/integration/executors/executors.py,sha256=Kzisp1eKufGCWrHIw4mmAj-l1U
|
|
|
122
122
|
uncountable/integration/executors/generic_upload_executor.py,sha256=z0HfvuBR1wUbRpMVxJQ5Jlzbdk8G7YmAGENmze85Tr8,12076
|
|
123
123
|
uncountable/integration/executors/script_executor.py,sha256=BBQ9f0l7uH2hgKf60jtm-pONzwk-EeOhM2qBAbv_URo,846
|
|
124
124
|
uncountable/integration/http_server/__init__.py,sha256=WY2HMcL0UCAGYv8y6Pz-j0azbDGXwubFF21EH_zNPkc,189
|
|
125
|
-
uncountable/integration/http_server/types.py,sha256=
|
|
125
|
+
uncountable/integration/http_server/types.py,sha256=3JJSulRfv784SbXnXo1Pywto7RwGxgS-iJ2-a6TOnDI,1869
|
|
126
126
|
uncountable/integration/queue_runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
127
127
|
uncountable/integration/queue_runner/job_scheduler.py,sha256=Roh7-mTj6rwMzFhBXv7hASNS2dMeTcAZEynJGVjkhEs,6080
|
|
128
128
|
uncountable/integration/queue_runner/queue_runner.py,sha256=N4sUXmlGzVquybiJ7NQZavCJOBGrxBj6k7mb-TITaN0,1139
|
|
@@ -145,10 +145,10 @@ uncountable/integration/queue_runner/datastore/model.py,sha256=8-RI5A2yPZVGBLWIN
|
|
|
145
145
|
uncountable/integration/secret_retrieval/__init__.py,sha256=3QXVj35w8rRMxVvmmsViFYDi3lcb3g70incfalOEm6o,87
|
|
146
146
|
uncountable/integration/secret_retrieval/retrieve_secret.py,sha256=LBEf18KHtXZxg-ZZ80stJ1vW39AWf0CQllP6pNu3Eq8,2994
|
|
147
147
|
uncountable/integration/webhook_server/entrypoint.py,sha256=NQawXl_JCRojdVniS5RF7dobQQKW_Wy03bwy-uXknuA,3441
|
|
148
|
-
uncountable/types/__init__.py,sha256=
|
|
148
|
+
uncountable/types/__init__.py,sha256=rTLpqWlx5eqZ_O1hqnBp7rHWyGII3qyscNYortb6EgU,10696
|
|
149
149
|
uncountable/types/async_batch.py,sha256=yCCWrrLQfxXVqZp-KskxLBNkNmuELdz4PJjx8ULppgs,662
|
|
150
|
-
uncountable/types/async_batch_processor.py,sha256=
|
|
151
|
-
uncountable/types/async_batch_t.py,sha256=
|
|
150
|
+
uncountable/types/async_batch_processor.py,sha256=hvTGI4NNBlHF1q6ec_DuZhLSvX8F32L9lFztNLNjWHw,23451
|
|
151
|
+
uncountable/types/async_batch_t.py,sha256=mAQ2AXao_v76e7hZGzUCoSroq2Kf2FVz6hmmMX0icHo,3836
|
|
152
152
|
uncountable/types/async_jobs.py,sha256=JI0ScfawaqMRbJ2jbgW3YQLhijPnBeYdMnZJjygSxHg,322
|
|
153
153
|
uncountable/types/async_jobs_t.py,sha256=u4xd3i512PZ-9592Q2ZgWh_faMiI4UMm0F_gOmZnerI,1389
|
|
154
154
|
uncountable/types/auth_retrieval.py,sha256=770zjN1K9EF5zs1Xml7x6ke6Hkze7rcMT5FdDVCIl9M,549
|
|
@@ -159,7 +159,7 @@ uncountable/types/calculations.py,sha256=fApOFpgBemt_t7IVneVR0VdI3X5EOxiG6Xhzr6R
|
|
|
159
159
|
uncountable/types/calculations_t.py,sha256=pl-lhjyDQuj11Sf9g1-0BsSkN7Ez8UxDp8-KMQ_3enM,709
|
|
160
160
|
uncountable/types/chemical_structure.py,sha256=ujyragaD26-QG5jgKnWhO7TN3N1V9b_04T2WhqNYxxo,281
|
|
161
161
|
uncountable/types/chemical_structure_t.py,sha256=VFFyits_vx4t5L2euu_qFiSpsGJjURkDPr3ISnr3nPc,855
|
|
162
|
-
uncountable/types/client_base.py,sha256=
|
|
162
|
+
uncountable/types/client_base.py,sha256=HK2EHdHiNRbtHj4BqTGo4-hxsFepJ45UuY2RYwuhAJw,78005
|
|
163
163
|
uncountable/types/client_config.py,sha256=qLpHt4O_B098CyN6qQajoxZ2zjZ1DILXLUEGyyGP0TQ,280
|
|
164
164
|
uncountable/types/client_config_t.py,sha256=yTFIYAitMrcc4oV9J-HADODS_Hwi45z-piz7rr7QT04,781
|
|
165
165
|
uncountable/types/curves.py,sha256=QyEyC20jsG-LGKVx6miiF-w70vKMwNkILFBDIJ5Ok9g,345
|
|
@@ -194,6 +194,8 @@ uncountable/types/integrations.py,sha256=0fOhtbLIOl9w1GP9J3PTagRU8mjOKV48JNLLH3S
|
|
|
194
194
|
uncountable/types/integrations_t.py,sha256=ihyhuMDKtJarQ19OppS0fYpJUYd8o5-w6YCDE440O-w,1871
|
|
195
195
|
uncountable/types/job_definition.py,sha256=hYp5jPYLLYm3NKEqzQrQfXL0Ms5KgEQGTON13YWSPYk,1804
|
|
196
196
|
uncountable/types/job_definition_t.py,sha256=E4IQvcYF3VDHbwRlvopy8y-HNAyEMZpwy7jkmp74fgQ,9563
|
|
197
|
+
uncountable/types/notifications.py,sha256=ZGr1ULMG3cPMED83NbMjrjmgVzCeOTS1Tc-pFTNuY4Y,600
|
|
198
|
+
uncountable/types/notifications_t.py,sha256=qS2mhCkYHFPe2XtBespABJ3dNvisxrmIw_r8ZlUCh_g,2444
|
|
197
199
|
uncountable/types/outputs.py,sha256=I6zP2WHXg_jXgMqmuEJuJOlsjKjQGHjfs1JOwW9YxBM,260
|
|
198
200
|
uncountable/types/outputs_t.py,sha256=atsOkBBgnMeCgPaKPidk9eNouWVnynSrMI_ZbqxRJeY,795
|
|
199
201
|
uncountable/types/overrides.py,sha256=fOvj8P9K9ul8fnTwA--l140EWHuc1BFq8tXgtBkYld4,410
|
|
@@ -281,11 +283,13 @@ uncountable/types/api/inputs/set_input_subcategories.py,sha256=w5U6eXes5KquPW1Uc
|
|
|
281
283
|
uncountable/types/api/inputs/set_intermediate_type.py,sha256=S1RLI2RtrRze0NdMUfK2nwR4Twn_DnLnWNsg0-ivi_A,1431
|
|
282
284
|
uncountable/types/api/integrations/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
283
285
|
uncountable/types/api/integrations/publish_realtime_data.py,sha256=-5r2U78AwKUCpModcUIchVIZ9b7L-Ln6O6T-9d57M2A,1181
|
|
286
|
+
uncountable/types/api/integrations/push_notification.py,sha256=_ycqsGSd7pdt480JWCwMf-SoL_XIwWzEF-lyWoPmqIY,1404
|
|
284
287
|
uncountable/types/api/material_families/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
285
288
|
uncountable/types/api/material_families/update_entity_material_families.py,sha256=qWJgAKH0MayadXvxckePCdo9yd34QXOmGZ7cKz5VLNo,1761
|
|
286
289
|
uncountable/types/api/outputs/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
287
290
|
uncountable/types/api/outputs/get_output_data.py,sha256=luGoQZzbZsGIzo2dXMD5f6rDlXEgBjnnUU9n5T-VL9Q,3069
|
|
288
291
|
uncountable/types/api/outputs/get_output_names.py,sha256=myxLS1YedzWlKs3st64jmM9XMUphrUltxKISBz4pVSo,1539
|
|
292
|
+
uncountable/types/api/outputs/get_output_organization.py,sha256=uxfpuyu7wCYSSAt4pn98voyBfmP4sjZjvL0I65eZH_s,6602
|
|
289
293
|
uncountable/types/api/outputs/resolve_output_conditions.py,sha256=X8qHd_xZUxIlmfPyLyaBbVjdH_dIN4tj7xVuFFvaQsw,2578
|
|
290
294
|
uncountable/types/api/permissions/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
291
295
|
uncountable/types/api/permissions/set_core_permissions.py,sha256=RtI5l9iyR80mkh9PzpCvn02xfCKsuvHYYCXDr48FT_Q,3651
|
|
@@ -334,7 +338,7 @@ uncountable/types/api/uploader/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr
|
|
|
334
338
|
uncountable/types/api/uploader/invoke_uploader.py,sha256=Bj7Dq4A90k00suacwk3bLA_dCb2aovS1kAbVam2AQnM,1395
|
|
335
339
|
uncountable/types/api/user/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
336
340
|
uncountable/types/api/user/get_current_user_info.py,sha256=Avqi_RXtRgbefrT_dwJ9MrO6eDNSSa_Nu650FSuESlg,1109
|
|
337
|
-
uncountablepythonsdk-0.0.
|
|
338
|
-
uncountablepythonsdk-0.0.
|
|
339
|
-
uncountablepythonsdk-0.0.
|
|
340
|
-
uncountablepythonsdk-0.0.
|
|
341
|
+
uncountablepythonsdk-0.0.124.dist-info/METADATA,sha256=kv-9cIHdi6N5BJaY3zYz6Lmq7wDQnEV2h9xBgcRNJg8,2174
|
|
342
|
+
uncountablepythonsdk-0.0.124.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
343
|
+
uncountablepythonsdk-0.0.124.dist-info/top_level.txt,sha256=1UVGjAU-6hJY9qw2iJ7nCBeEwZ793AEN5ZfKX9A1uj4,31
|
|
344
|
+
uncountablepythonsdk-0.0.124.dist-info/RECORD,,
|
|
File without changes
|
{uncountablepythonsdk-0.0.123.dist-info → uncountablepythonsdk-0.0.124.dist-info}/top_level.txt
RENAMED
|
File without changes
|