UncountablePythonSDK 0.0.166__py3-none-any.whl → 0.0.168__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.
- pkgs/argument_parser/argument_parser.py +5 -3
- pkgs/filesystem_utils/_sftp_session.py +3 -0
- pkgs/filesystem_utils/file_type_utils.py +1 -0
- uncountable/core/client.py +1 -1
- uncountable/core/file_upload.py +1 -1
- uncountable/core/query/builder.py +65 -51
- uncountable/integration/executors/executors.py +2 -2
- uncountable/integration/queue_runner/job_scheduler.py +4 -4
- uncountable/integration/scheduler.py +7 -7
- uncountable/integration/telemetry.py +12 -2
- uncountable/integration/webhook_server/entrypoint.py +1 -1
- uncountable/types/__init__.py +4 -0
- uncountable/types/api/condition_parameters/upsert_condition_match.py +8 -6
- uncountable/types/api/condition_parameters/upsert_condition_matches.py +161 -0
- uncountable/types/client_base.py +21 -0
- uncountable/types/condition_match.py +7 -0
- uncountable/types/condition_match_t.py +22 -0
- {uncountablepythonsdk-0.0.166.dist-info → uncountablepythonsdk-0.0.168.dist-info}/METADATA +1 -1
- {uncountablepythonsdk-0.0.166.dist-info → uncountablepythonsdk-0.0.168.dist-info}/RECORD +21 -18
- {uncountablepythonsdk-0.0.166.dist-info → uncountablepythonsdk-0.0.168.dist-info}/WHEEL +0 -0
- {uncountablepythonsdk-0.0.166.dist-info → uncountablepythonsdk-0.0.168.dist-info}/top_level.txt +0 -0
|
@@ -426,9 +426,11 @@ def _build_parser_inner(
|
|
|
426
426
|
return inner
|
|
427
427
|
|
|
428
428
|
v_parser = _build_parser_inner(args[1], context, type_var_map)
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
429
|
+
|
|
430
|
+
def parse_dict(value: typing.Any) -> typing.Any:
|
|
431
|
+
return origin((key_parser(k), v_parser(v)) for k, v in value.items())
|
|
432
|
+
|
|
433
|
+
return parse_dict
|
|
432
434
|
|
|
433
435
|
if origin == typing.Literal:
|
|
434
436
|
valid_values: set[T] = set(typing.get_args(parsed_type))
|
|
@@ -67,6 +67,7 @@ class SFTPSession(FileSystemSession):
|
|
|
67
67
|
def __init__(self, sftp_config: FileSystemSFTPConfig) -> None:
|
|
68
68
|
super().__init__()
|
|
69
69
|
self.host: str = sftp_config.ip
|
|
70
|
+
self.port: int = sftp_config.port
|
|
70
71
|
self.username: str = sftp_config.username
|
|
71
72
|
self.key_file: str | paramiko.PKey | None = (
|
|
72
73
|
sftp_config.pem_path
|
|
@@ -81,6 +82,7 @@ class SFTPSession(FileSystemSession):
|
|
|
81
82
|
if self.key_file is not None:
|
|
82
83
|
self.connection = pysftp.Connection(
|
|
83
84
|
self.host,
|
|
85
|
+
port=self.port,
|
|
84
86
|
username=self.username,
|
|
85
87
|
private_key=self.key_file,
|
|
86
88
|
cnopts=cnopts,
|
|
@@ -88,6 +90,7 @@ class SFTPSession(FileSystemSession):
|
|
|
88
90
|
elif self.password is not None:
|
|
89
91
|
self.connection = pysftp.Connection(
|
|
90
92
|
self.host,
|
|
93
|
+
port=self.port,
|
|
91
94
|
username=self.username,
|
|
92
95
|
password=self.password,
|
|
93
96
|
cnopts=cnopts,
|
uncountable/core/client.py
CHANGED
|
@@ -264,7 +264,7 @@ class Client(ClientMethods):
|
|
|
264
264
|
}
|
|
265
265
|
with push_scope_optional(self._cfg.logger, "api_call", attributes=attributes):
|
|
266
266
|
if self._cfg.logger is not None:
|
|
267
|
-
self._cfg.logger.
|
|
267
|
+
self._cfg.logger.log_debug(api_request.endpoint, attributes=attributes)
|
|
268
268
|
timeout = (
|
|
269
269
|
api_request.request_options.timeout_secs
|
|
270
270
|
if api_request.request_options is not None
|
uncountable/core/file_upload.py
CHANGED
|
@@ -142,7 +142,7 @@ class FileUploader:
|
|
|
142
142
|
self._logger, "upload_file", attributes=attributes
|
|
143
143
|
):
|
|
144
144
|
if self._logger is not None:
|
|
145
|
-
self._logger.
|
|
145
|
+
self._logger.log_debug("Uploading file", attributes=attributes)
|
|
146
146
|
with file_upload_data(file_upload) as file_bytes:
|
|
147
147
|
if file_bytes.bytes_data.read(1) == b"":
|
|
148
148
|
raise UploadFailed(
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
-
import time
|
|
5
4
|
from copy import copy
|
|
6
5
|
from dataclasses import make_dataclass
|
|
7
6
|
from decimal import Decimal
|
|
8
|
-
from typing import Self
|
|
7
|
+
from typing import Callable, Self
|
|
9
8
|
|
|
10
9
|
from pkgs.argument_parser import CachedParser
|
|
11
10
|
from pkgs.serialization.serial_class import serial_class
|
|
@@ -29,8 +28,7 @@ from uncountable.types import (
|
|
|
29
28
|
from uncountable.types.api.entity import list_entities as list_entities_t
|
|
30
29
|
from uncountable.types.api.files.download_file import FileDownloadQueryEntityField
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
_ASYNC_EXPORT_POLL_INTERVAL_SECONDS = 1
|
|
31
|
+
_FETCH_ROW_LIMIT = 100
|
|
34
32
|
|
|
35
33
|
|
|
36
34
|
class _AsyncExportJob(QueryRow):
|
|
@@ -99,7 +97,9 @@ class QueryBuilder[QueryRowT: QueryRow]:
|
|
|
99
97
|
)
|
|
100
98
|
return branch
|
|
101
99
|
|
|
102
|
-
def _fetch(self, limit: int
|
|
100
|
+
def _fetch(self, limit: int, offset: int = 0) -> list[QueryRowT]:
|
|
101
|
+
if limit > _FETCH_ROW_LIMIT:
|
|
102
|
+
raise ValueError(f"Fetch row limit cannot exceed {_FETCH_ROW_LIMIT}")
|
|
103
103
|
rows = self._client.fetch_listing(
|
|
104
104
|
entity_type=self._base_type,
|
|
105
105
|
columns=list(self._column_identifiers),
|
|
@@ -107,7 +107,6 @@ class QueryBuilder[QueryRowT: QueryRow]:
|
|
|
107
107
|
limit=limit,
|
|
108
108
|
offset=offset,
|
|
109
109
|
).results
|
|
110
|
-
|
|
111
110
|
return [self._parse_row(row.column_values) for row in rows]
|
|
112
111
|
|
|
113
112
|
def _hook_after_parse_row(self, row: QueryRowT) -> None:
|
|
@@ -124,13 +123,13 @@ class QueryBuilder[QueryRowT: QueryRow]:
|
|
|
124
123
|
return parsed_model
|
|
125
124
|
|
|
126
125
|
def one(self) -> QueryRowT:
|
|
127
|
-
results = self._fetch()
|
|
126
|
+
results = self._fetch(limit=2)
|
|
128
127
|
if len(results) != 1:
|
|
129
128
|
raise ValueError(f"Expected one result, received {len(results)}")
|
|
130
129
|
return results[0]
|
|
131
130
|
|
|
132
131
|
def one_or_none(self) -> QueryRowT | None:
|
|
133
|
-
results = self._fetch()
|
|
132
|
+
results = self._fetch(limit=2)
|
|
134
133
|
if len(results) > 1:
|
|
135
134
|
raise ValueError(f"Expected one result, received {len(results)}")
|
|
136
135
|
if len(results) == 0:
|
|
@@ -142,59 +141,74 @@ class QueryBuilder[QueryRowT: QueryRow]:
|
|
|
142
141
|
return None if len(results) == 0 else results[0]
|
|
143
142
|
|
|
144
143
|
def all(self) -> list[QueryRowT]:
|
|
145
|
-
results = self._fetch()
|
|
146
|
-
if len(results) <
|
|
144
|
+
results = self._fetch(limit=_FETCH_ROW_LIMIT)
|
|
145
|
+
if len(results) < _FETCH_ROW_LIMIT:
|
|
147
146
|
return results
|
|
148
|
-
return self._await_async_export()
|
|
149
147
|
|
|
150
|
-
|
|
148
|
+
# Generate an async listing export if the number of results >= 100
|
|
149
|
+
poll_for_async_export_results = self._submit_async_export()
|
|
150
|
+
|
|
151
|
+
# Resolve exponentially increasing pagination batches until all rows are fetched or the async job completes
|
|
152
|
+
iteration_count: int = 0
|
|
153
|
+
while True:
|
|
154
|
+
for _ in range(2**iteration_count):
|
|
155
|
+
rows = self._fetch(limit=_FETCH_ROW_LIMIT, offset=len(results))
|
|
156
|
+
results.extend(rows)
|
|
157
|
+
if len(rows) < _FETCH_ROW_LIMIT:
|
|
158
|
+
return results
|
|
159
|
+
|
|
160
|
+
if export_results := poll_for_async_export_results():
|
|
161
|
+
return export_results
|
|
162
|
+
iteration_count += 1
|
|
163
|
+
|
|
164
|
+
def _submit_async_export(self) -> Callable[[], list[QueryRowT] | None]:
|
|
165
|
+
"""
|
|
166
|
+
Requests an async export of the query results. Returns a closure for polling the results of the export.
|
|
167
|
+
"""
|
|
151
168
|
async_job_entity = self._client.export_listing(
|
|
152
169
|
entity_type=self._base_type,
|
|
153
170
|
columns=list(self._column_identifiers),
|
|
154
171
|
filters=listing_t.FilterNodeColumnAnd(filters=tuple(self._filters)),
|
|
155
172
|
).entity
|
|
156
173
|
if async_job_entity is None:
|
|
157
|
-
raise ValueError("
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
174
|
+
raise ValueError("async listing export generation failed")
|
|
175
|
+
async_job_status: async_jobs_t.AsyncJobStatus | str | None = None
|
|
176
|
+
|
|
177
|
+
def poll_for_results() -> list[QueryRowT] | None:
|
|
178
|
+
nonlocal async_job_status
|
|
179
|
+
if async_job_status == async_jobs_t.AsyncJobStatus.ERROR:
|
|
180
|
+
return None
|
|
181
|
+
async_job_status = (
|
|
182
|
+
QueryBuilder(client=self._client, model=_AsyncExportJob)
|
|
165
183
|
.filter(_AsyncExportJob.id == async_job_entity.id)
|
|
166
184
|
.one()
|
|
167
185
|
.status
|
|
168
|
-
)
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
),
|
|
176
|
-
type=entity_t.EntityType.ASYNC_JOB,
|
|
177
|
-
),
|
|
178
|
-
field_key=identifier_t.IdentifierKeyRefName(
|
|
179
|
-
ref_name="unc_async_listing_export_file"
|
|
186
|
+
)
|
|
187
|
+
if async_job_status == async_jobs_t.AsyncJobStatus.COMPLETED:
|
|
188
|
+
export_file = self._client.download_files(
|
|
189
|
+
file_query=FileDownloadQueryEntityField(
|
|
190
|
+
entity=entity_t.EntityIdentifier(
|
|
191
|
+
identifier_key=identifier_t.IdentifierKeyId(
|
|
192
|
+
id=async_job_entity.id
|
|
180
193
|
),
|
|
194
|
+
type=entity_t.EntityType.ASYNC_JOB,
|
|
195
|
+
),
|
|
196
|
+
field_key=identifier_t.IdentifierKeyRefName(
|
|
197
|
+
ref_name="unc_async_listing_export_file"
|
|
198
|
+
),
|
|
199
|
+
)
|
|
200
|
+
)[0].data.read()
|
|
201
|
+
return [
|
|
202
|
+
self._parse_row(row.column_values)
|
|
203
|
+
for row in CachedParser(list_entities_t.Data)
|
|
204
|
+
.parse_api(
|
|
205
|
+
json.loads(
|
|
206
|
+
export_file,
|
|
207
|
+
parse_float=Decimal,
|
|
181
208
|
)
|
|
182
|
-
)
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
json.loads(
|
|
189
|
-
export_file,
|
|
190
|
-
parse_float=Decimal,
|
|
191
|
-
)
|
|
192
|
-
)
|
|
193
|
-
.results
|
|
194
|
-
]
|
|
195
|
-
case async_jobs_t.AsyncJobStatus.ERROR:
|
|
196
|
-
raise ValueError("Listing export failed")
|
|
197
|
-
time.sleep(_ASYNC_EXPORT_POLL_INTERVAL_SECONDS)
|
|
198
|
-
raise TimeoutError(
|
|
199
|
-
f"Async listing export timed out after {_ASYNC_EXPORT_TIMEOUT_SECONDS} seconds"
|
|
200
|
-
)
|
|
209
|
+
)
|
|
210
|
+
.results
|
|
211
|
+
]
|
|
212
|
+
return None
|
|
213
|
+
|
|
214
|
+
return poll_for_results
|
|
@@ -93,7 +93,7 @@ def execute_job(
|
|
|
93
93
|
job = resolve_executor(job_definition.executor, profile_metadata)
|
|
94
94
|
job_location = f"{job.__class__.__module__}.{job.__class__.__name__}"
|
|
95
95
|
|
|
96
|
-
job_logger.
|
|
96
|
+
job_logger.log_debug(f"Starting job: `{job_location}`")
|
|
97
97
|
|
|
98
98
|
run_entity: entity_t.Entity | None = None
|
|
99
99
|
try:
|
|
@@ -115,7 +115,7 @@ def execute_job(
|
|
|
115
115
|
result = job_definition_t.JobResult(success=False)
|
|
116
116
|
|
|
117
117
|
submitted_batch_job_ids = args.batch_processor.get_submitted_job_ids()
|
|
118
|
-
job_logger.
|
|
118
|
+
job_logger.log_debug(
|
|
119
119
|
f"Completed job: `{job_location}` (success={result.success})",
|
|
120
120
|
attributes={
|
|
121
121
|
"submitted_batch_job_ids": submitted_batch_job_ids,
|
|
@@ -136,7 +136,7 @@ async def start_scheduler(
|
|
|
136
136
|
job_payload=payload,
|
|
137
137
|
job_ref_name=job_ref_name,
|
|
138
138
|
)
|
|
139
|
-
logger.
|
|
139
|
+
logger.log_debug(
|
|
140
140
|
"Job submitted successfully.",
|
|
141
141
|
attributes={"job.queued_job_uuid": queued_job.queued_job_uuid},
|
|
142
142
|
)
|
|
@@ -168,7 +168,7 @@ async def start_scheduler(
|
|
|
168
168
|
)
|
|
169
169
|
)
|
|
170
170
|
|
|
171
|
-
logger.
|
|
171
|
+
logger.log_debug(
|
|
172
172
|
"Job cancelled successfully.",
|
|
173
173
|
attributes={"job.queued_job_uuid": command.queued_job_uuid},
|
|
174
174
|
)
|
|
@@ -201,10 +201,10 @@ async def start_scheduler(
|
|
|
201
201
|
def _handle_vaccuum_queued_jobs_command(
|
|
202
202
|
command: CommandVaccuumQueuedJobs,
|
|
203
203
|
) -> None:
|
|
204
|
-
logger.
|
|
204
|
+
logger.log_debug("Vaccuuming queued jobs...")
|
|
205
205
|
deleted_uuids = datastore.vaccuum_queued_jobs()
|
|
206
206
|
|
|
207
|
-
logger.
|
|
207
|
+
logger.log_debug(
|
|
208
208
|
"Queued jobs vacuumed successfully.",
|
|
209
209
|
attributes={"job.queued_job_uuids": deleted_uuids},
|
|
210
210
|
)
|
|
@@ -71,7 +71,7 @@ ProcessAlarm = ProcessAlarmRestart | ProcessAlarmShutdownAll
|
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
def handle_shutdown(logger: Logger, processes: dict[ProcessName, ProcessInfo]) -> None:
|
|
74
|
-
logger.
|
|
74
|
+
logger.log_debug("received shutdown command, shutting down sub-processes")
|
|
75
75
|
for proc_info in processes.values():
|
|
76
76
|
if proc_info.is_alive:
|
|
77
77
|
proc_info.process.terminate()
|
|
@@ -83,7 +83,7 @@ def handle_shutdown(logger: Logger, processes: dict[ProcessName, ProcessInfo]) -
|
|
|
83
83
|
and len(still_living_processes) > 0
|
|
84
84
|
):
|
|
85
85
|
current_loop_processes = [*still_living_processes]
|
|
86
|
-
logger.
|
|
86
|
+
logger.log_debug(
|
|
87
87
|
"waiting for sub-processes to shut down",
|
|
88
88
|
attributes={
|
|
89
89
|
"still_living_processes": [
|
|
@@ -94,7 +94,7 @@ def handle_shutdown(logger: Logger, processes: dict[ProcessName, ProcessInfo]) -
|
|
|
94
94
|
still_living_processes = []
|
|
95
95
|
for proc_info in current_loop_processes:
|
|
96
96
|
if not proc_info.is_alive:
|
|
97
|
-
logger.
|
|
97
|
+
logger.log_debug(f"{proc_info.name} shut down successfully")
|
|
98
98
|
else:
|
|
99
99
|
still_living_processes.append(proc_info)
|
|
100
100
|
time.sleep(1)
|
|
@@ -121,7 +121,7 @@ def restart_process(
|
|
|
121
121
|
processes[ProcessName.QUEUE_RUNNER] = new_info
|
|
122
122
|
try:
|
|
123
123
|
_wait_queue_runner_online()
|
|
124
|
-
logger.
|
|
124
|
+
logger.log_debug("queue runner restarted successfully")
|
|
125
125
|
except Exception as e:
|
|
126
126
|
logger.log_exception(e)
|
|
127
127
|
logger.log_error(
|
|
@@ -135,13 +135,13 @@ def restart_process(
|
|
|
135
135
|
cron_proc.start()
|
|
136
136
|
new_info = ProcessInfo(name=ProcessName.CRON_SERVER, process=cron_proc)
|
|
137
137
|
processes[ProcessName.CRON_SERVER] = new_info
|
|
138
|
-
logger.
|
|
138
|
+
logger.log_debug("cron server restarted successfully")
|
|
139
139
|
|
|
140
140
|
case ProcessName.UWSGI:
|
|
141
141
|
uwsgi_proc: AnyProcess = subprocess.Popen(["uwsgi", "--die-on-term"])
|
|
142
142
|
new_info = ProcessInfo(name=ProcessName.UWSGI, process=uwsgi_proc)
|
|
143
143
|
processes[ProcessName.UWSGI] = new_info
|
|
144
|
-
logger.
|
|
144
|
+
logger.log_debug("uwsgi restarted successfully")
|
|
145
145
|
|
|
146
146
|
|
|
147
147
|
def check_process_alarms(
|
|
@@ -188,7 +188,7 @@ def main() -> None:
|
|
|
188
188
|
|
|
189
189
|
def add_process(process: ProcessInfo) -> None:
|
|
190
190
|
processes[process.name] = process
|
|
191
|
-
logger.
|
|
191
|
+
logger.log_debug(f"started process {process.name}")
|
|
192
192
|
|
|
193
193
|
def _start_queue_runner() -> None:
|
|
194
194
|
runner_process = multiprocessing.Process(target=start_queue_runner)
|
|
@@ -94,6 +94,7 @@ def get_otel_logger() -> OTELLogger:
|
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
class LogSeverity(StrEnum):
|
|
97
|
+
DEBUG = "Debug"
|
|
97
98
|
INFO = "Info"
|
|
98
99
|
WARN = "Warn"
|
|
99
100
|
ERROR = "Error"
|
|
@@ -102,6 +103,8 @@ class LogSeverity(StrEnum):
|
|
|
102
103
|
def _get_severity_number(severity: LogSeverity) -> _logs.SeverityNumber:
|
|
103
104
|
"""Map LogSeverity to OpenTelemetry SeverityNumber for Datadog."""
|
|
104
105
|
match severity:
|
|
106
|
+
case LogSeverity.DEBUG:
|
|
107
|
+
return _logs.SeverityNumber.DEBUG
|
|
105
108
|
case LogSeverity.INFO:
|
|
106
109
|
return _logs.SeverityNumber.INFO
|
|
107
110
|
case LogSeverity.WARN:
|
|
@@ -172,6 +175,13 @@ class Logger:
|
|
|
172
175
|
def bind(self, *, attributes: Attributes) -> None:
|
|
173
176
|
self._bound_attributes.update(attributes)
|
|
174
177
|
|
|
178
|
+
def log_debug(self, message: str, *, attributes: Attributes | None = None) -> None:
|
|
179
|
+
self._emit_log(
|
|
180
|
+
message=message, severity=LogSeverity.DEBUG, attributes=attributes
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
# Use log_info for user-facing job logs (e.g. example_* and custom executor output).
|
|
184
|
+
# SDK-internal instrumentation should use log_debug instead.
|
|
175
185
|
def log_info(self, message: str, *, attributes: Attributes | None = None) -> None:
|
|
176
186
|
self._emit_log(
|
|
177
187
|
message=message, severity=LogSeverity.INFO, attributes=attributes
|
|
@@ -268,7 +278,7 @@ class PerJobResourceTracker:
|
|
|
268
278
|
self.max_rss = max(self.max_rss, rss)
|
|
269
279
|
now = time.monotonic()
|
|
270
280
|
if now - last_log_time >= self.log_interval:
|
|
271
|
-
self.logger.
|
|
281
|
+
self.logger.log_debug(
|
|
272
282
|
"Job resource usage (periodic)",
|
|
273
283
|
attributes=self._current_stats(),
|
|
274
284
|
)
|
|
@@ -310,7 +320,7 @@ class PerJobResourceTracker:
|
|
|
310
320
|
),
|
|
311
321
|
)
|
|
312
322
|
return
|
|
313
|
-
self.logger.
|
|
323
|
+
self.logger.log_debug("Job resource usage summary", attributes=stats)
|
|
314
324
|
return
|
|
315
325
|
|
|
316
326
|
def summary(self) -> Attributes:
|
uncountable/types/__init__.py
CHANGED
|
@@ -20,6 +20,7 @@ from .api.recipes import clear_recipe_outputs as clear_recipe_outputs_t
|
|
|
20
20
|
from . import client_config_t as client_config_t
|
|
21
21
|
from .api.uploader import complete_async_parse as complete_async_parse_t
|
|
22
22
|
from .api.runsheet import complete_async_upload as complete_async_upload_t
|
|
23
|
+
from . import condition_match_t as condition_match_t
|
|
23
24
|
from .api.chemical import convert_chemical_formats as convert_chemical_formats_t
|
|
24
25
|
from .api.entity import create_entities as create_entities_t
|
|
25
26
|
from .api.entity import create_entity as create_entity_t
|
|
@@ -145,6 +146,7 @@ from .api.material_families import update_entity_material_families as update_ent
|
|
|
145
146
|
from .api.outputs import update_output_condition_parameter as update_output_condition_parameter_t
|
|
146
147
|
from . import uploader_t as uploader_t
|
|
147
148
|
from .api.condition_parameters import upsert_condition_match as upsert_condition_match_t
|
|
149
|
+
from .api.condition_parameters import upsert_condition_matches as upsert_condition_matches_t
|
|
148
150
|
from .api.field_options import upsert_field_options as upsert_field_options_t
|
|
149
151
|
from .api.recipes import upsert_recipe_workflow_step as upsert_recipe_workflow_step_t
|
|
150
152
|
from .api.recipes import upsert_step_relationships as upsert_step_relationships_t
|
|
@@ -172,6 +174,7 @@ __all__: list[str] = [
|
|
|
172
174
|
"client_config_t",
|
|
173
175
|
"complete_async_parse_t",
|
|
174
176
|
"complete_async_upload_t",
|
|
177
|
+
"condition_match_t",
|
|
175
178
|
"convert_chemical_formats_t",
|
|
176
179
|
"create_entities_t",
|
|
177
180
|
"create_entity_t",
|
|
@@ -297,6 +300,7 @@ __all__: list[str] = [
|
|
|
297
300
|
"update_output_condition_parameter_t",
|
|
298
301
|
"uploader_t",
|
|
299
302
|
"upsert_condition_match_t",
|
|
303
|
+
"upsert_condition_matches_t",
|
|
300
304
|
"upsert_field_options_t",
|
|
301
305
|
"upsert_recipe_workflow_step_t",
|
|
302
306
|
"upsert_step_relationships_t",
|
|
@@ -6,11 +6,12 @@ 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
|
|
10
9
|
import dataclasses
|
|
11
10
|
from pkgs.serialization import serial_class
|
|
11
|
+
from pkgs.serialization import serial_alias_annotation
|
|
12
12
|
from ... import async_batch_t
|
|
13
13
|
from ... import base_t
|
|
14
|
+
from ... import condition_match_t
|
|
14
15
|
from ... import identifier_t
|
|
15
16
|
|
|
16
17
|
__all__: list[str] = [
|
|
@@ -42,11 +43,12 @@ class ConditionParameter:
|
|
|
42
43
|
|
|
43
44
|
|
|
44
45
|
# DO NOT MODIFY -- This file is generated by type_spec
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
MatchType = typing.Annotated[
|
|
47
|
+
condition_match_t.MatchType,
|
|
48
|
+
serial_alias_annotation(
|
|
49
|
+
named_type_path="sdk.api.condition_parameters.upsert_condition_match.MatchType",
|
|
50
|
+
),
|
|
51
|
+
]
|
|
50
52
|
|
|
51
53
|
|
|
52
54
|
# DO NOT MODIFY -- This file is generated by type_spec
|
|
@@ -0,0 +1,161 @@
|
|
|
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 pkgs.serialization import serial_union_annotation
|
|
12
|
+
from ... import async_batch_t
|
|
13
|
+
from ... import base_t
|
|
14
|
+
from ... import condition_match_t
|
|
15
|
+
from ... import identifier_t
|
|
16
|
+
|
|
17
|
+
__all__: list[str] = [
|
|
18
|
+
"Arguments",
|
|
19
|
+
"ConditionParameter",
|
|
20
|
+
"ConditionParameterAll",
|
|
21
|
+
"ConditionParameterEqCategorical",
|
|
22
|
+
"ConditionParameterEqNumeric",
|
|
23
|
+
"ConditionParameterRange",
|
|
24
|
+
"Data",
|
|
25
|
+
"ENDPOINT_METHOD",
|
|
26
|
+
"ENDPOINT_PATH",
|
|
27
|
+
"UpsertArgs",
|
|
28
|
+
"UpsertArgsOutputConditions",
|
|
29
|
+
"UpsertArgsParameters",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
ENDPOINT_METHOD = "POST"
|
|
33
|
+
ENDPOINT_PATH = "api/external/condition_parameters/upsert_condition_matches"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
37
|
+
@serial_class(
|
|
38
|
+
named_type_path="sdk.api.condition_parameters.upsert_condition_matches.ConditionParameterAll",
|
|
39
|
+
parse_require={"match_type"},
|
|
40
|
+
)
|
|
41
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
42
|
+
class ConditionParameterAll:
|
|
43
|
+
condition_parameter_key: identifier_t.IdentifierKey
|
|
44
|
+
allow_null: bool
|
|
45
|
+
match_type: typing.Literal[condition_match_t.MatchType.ALL] = condition_match_t.MatchType.ALL
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
49
|
+
@serial_class(
|
|
50
|
+
named_type_path="sdk.api.condition_parameters.upsert_condition_matches.ConditionParameterEqNumeric",
|
|
51
|
+
parse_require={"match_type"},
|
|
52
|
+
)
|
|
53
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
54
|
+
class ConditionParameterEqNumeric:
|
|
55
|
+
condition_parameter_key: identifier_t.IdentifierKey
|
|
56
|
+
allow_null: bool
|
|
57
|
+
numeric_values: list[Decimal | None]
|
|
58
|
+
match_type: typing.Literal[condition_match_t.MatchType.EQ] = condition_match_t.MatchType.EQ
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
62
|
+
@serial_class(
|
|
63
|
+
named_type_path="sdk.api.condition_parameters.upsert_condition_matches.ConditionParameterEqCategorical",
|
|
64
|
+
parse_require={"match_type"},
|
|
65
|
+
)
|
|
66
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
67
|
+
class ConditionParameterEqCategorical:
|
|
68
|
+
condition_parameter_key: identifier_t.IdentifierKey
|
|
69
|
+
allow_null: bool
|
|
70
|
+
categorical_values: list[str | None]
|
|
71
|
+
match_type: typing.Literal[condition_match_t.MatchType.EQCATEGORICAL] = condition_match_t.MatchType.EQCATEGORICAL
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
75
|
+
@serial_class(
|
|
76
|
+
named_type_path="sdk.api.condition_parameters.upsert_condition_matches.ConditionParameterRange",
|
|
77
|
+
to_string_values={"max_value", "min_value"},
|
|
78
|
+
parse_require={"match_type"},
|
|
79
|
+
)
|
|
80
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
81
|
+
class ConditionParameterRange:
|
|
82
|
+
condition_parameter_key: identifier_t.IdentifierKey
|
|
83
|
+
allow_null: bool
|
|
84
|
+
min_value: Decimal
|
|
85
|
+
max_value: Decimal
|
|
86
|
+
match_type: typing.Literal[condition_match_t.MatchType.RANGE] = condition_match_t.MatchType.RANGE
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
90
|
+
ConditionParameter = typing.Annotated[
|
|
91
|
+
ConditionParameterAll | ConditionParameterEqNumeric | ConditionParameterEqCategorical | ConditionParameterRange,
|
|
92
|
+
serial_union_annotation(
|
|
93
|
+
named_type_path="sdk.api.condition_parameters.upsert_condition_matches.ConditionParameter",
|
|
94
|
+
discriminator="match_type",
|
|
95
|
+
discriminator_map={
|
|
96
|
+
"all": ConditionParameterAll,
|
|
97
|
+
"eq": ConditionParameterEqNumeric,
|
|
98
|
+
"eqCategorical": ConditionParameterEqCategorical,
|
|
99
|
+
"range": ConditionParameterRange,
|
|
100
|
+
},
|
|
101
|
+
),
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
106
|
+
@serial_class(
|
|
107
|
+
named_type_path="sdk.api.condition_parameters.upsert_condition_matches.UpsertArgsParameters",
|
|
108
|
+
parse_require={"kind"},
|
|
109
|
+
)
|
|
110
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
111
|
+
class UpsertArgsParameters:
|
|
112
|
+
condition_parameters: list[ConditionParameter]
|
|
113
|
+
kind: typing.Literal["condition_parameters"] = "condition_parameters"
|
|
114
|
+
name: str | None = None
|
|
115
|
+
existing_condition_match_key: identifier_t.IdentifierKey | None = None
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
119
|
+
@serial_class(
|
|
120
|
+
named_type_path="sdk.api.condition_parameters.upsert_condition_matches.UpsertArgsOutputConditions",
|
|
121
|
+
parse_require={"kind"},
|
|
122
|
+
)
|
|
123
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
124
|
+
class UpsertArgsOutputConditions:
|
|
125
|
+
output_condition_keys: list[identifier_t.IdentifierKey]
|
|
126
|
+
kind: typing.Literal["output_conditions"] = "output_conditions"
|
|
127
|
+
name: str | None = None
|
|
128
|
+
existing_condition_match_key: identifier_t.IdentifierKey | None = None
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
132
|
+
UpsertArgs = typing.Annotated[
|
|
133
|
+
UpsertArgsParameters | UpsertArgsOutputConditions,
|
|
134
|
+
serial_union_annotation(
|
|
135
|
+
named_type_path="sdk.api.condition_parameters.upsert_condition_matches.UpsertArgs",
|
|
136
|
+
discriminator="kind",
|
|
137
|
+
discriminator_map={
|
|
138
|
+
"condition_parameters": UpsertArgsParameters,
|
|
139
|
+
"output_conditions": UpsertArgsOutputConditions,
|
|
140
|
+
},
|
|
141
|
+
),
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
146
|
+
@serial_class(
|
|
147
|
+
named_type_path="sdk.api.condition_parameters.upsert_condition_matches.Arguments",
|
|
148
|
+
)
|
|
149
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
150
|
+
class Arguments:
|
|
151
|
+
upserts: list[UpsertArgs]
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
155
|
+
@serial_class(
|
|
156
|
+
named_type_path="sdk.api.condition_parameters.upsert_condition_matches.Data",
|
|
157
|
+
)
|
|
158
|
+
@dataclasses.dataclass(slots=base_t.ENABLE_SLOTS, kw_only=True) # type: ignore[literal-required]
|
|
159
|
+
class Data:
|
|
160
|
+
results: list[async_batch_t.AsyncBatchActionReturn]
|
|
161
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
uncountable/types/client_base.py
CHANGED
|
@@ -120,6 +120,7 @@ import uncountable.types.api.material_families.update_entity_material_families a
|
|
|
120
120
|
import uncountable.types.api.outputs.update_output_condition_parameter as update_output_condition_parameter_t
|
|
121
121
|
from uncountable.types import uploader_t
|
|
122
122
|
import uncountable.types.api.condition_parameters.upsert_condition_match as upsert_condition_match_t
|
|
123
|
+
import uncountable.types.api.condition_parameters.upsert_condition_matches as upsert_condition_matches_t
|
|
123
124
|
import uncountable.types.api.field_options.upsert_field_options as upsert_field_options_t
|
|
124
125
|
import uncountable.types.api.recipes.upsert_recipe_workflow_step as upsert_recipe_workflow_step_t
|
|
125
126
|
import uncountable.types.api.recipes.upsert_step_relationships as upsert_step_relationships_t
|
|
@@ -2457,6 +2458,26 @@ class ClientMethods(ABC):
|
|
|
2457
2458
|
)
|
|
2458
2459
|
return self.do_request(api_request=api_request, return_type=upsert_condition_match_t.Data)
|
|
2459
2460
|
|
|
2461
|
+
def upsert_condition_matches(
|
|
2462
|
+
self,
|
|
2463
|
+
*,
|
|
2464
|
+
upserts: list[upsert_condition_matches_t.UpsertArgs],
|
|
2465
|
+
_request_options: client_config_t.RequestOptions | None = None,
|
|
2466
|
+
) -> upsert_condition_matches_t.Data:
|
|
2467
|
+
"""Bulk variant of upsert_condition_match. Accepts a list of upsert arguments and applies them via a single batched database round-trip per bulk operation (insert, update, delete) through the shared upsert_condition_matches helper. Returns one AsyncBatchActionReturn per input in the same order.
|
|
2468
|
+
|
|
2469
|
+
"""
|
|
2470
|
+
args = upsert_condition_matches_t.Arguments(
|
|
2471
|
+
upserts=upserts,
|
|
2472
|
+
)
|
|
2473
|
+
api_request = APIRequest(
|
|
2474
|
+
method=upsert_condition_matches_t.ENDPOINT_METHOD,
|
|
2475
|
+
endpoint=upsert_condition_matches_t.ENDPOINT_PATH,
|
|
2476
|
+
args=args,
|
|
2477
|
+
request_options=_request_options,
|
|
2478
|
+
)
|
|
2479
|
+
return self.do_request(api_request=api_request, return_type=upsert_condition_matches_t.Data)
|
|
2480
|
+
|
|
2460
2481
|
def upsert_field_options(
|
|
2461
2482
|
self,
|
|
2462
2483
|
*,
|
|
@@ -0,0 +1,7 @@
|
|
|
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 .condition_match_t import MatchType as MatchType
|
|
7
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
|
|
11
|
+
__all__: list[str] = [
|
|
12
|
+
"MatchType",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# DO NOT MODIFY -- This file is generated by type_spec
|
|
17
|
+
class MatchType(StrEnum):
|
|
18
|
+
ALL = "all"
|
|
19
|
+
EQ = "eq"
|
|
20
|
+
EQCATEGORICAL = "eqCategorical"
|
|
21
|
+
RANGE = "range"
|
|
22
|
+
# 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.168
|
|
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
|
|
@@ -46,7 +46,7 @@ pkgs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
46
46
|
pkgs/argument_parser/__init__.py,sha256=kbarKmvTSa9lrt5hE0PUdJe3UmBHe8KbbnOLqupRZJE,1040
|
|
47
47
|
pkgs/argument_parser/_is_enum.py,sha256=Gw6jJa8nBwYGqXwwCZbSnWL8Rvr5alkg5lSVAqXtOZM,257
|
|
48
48
|
pkgs/argument_parser/_is_namedtuple.py,sha256=InCP2orqKbUYc4JsmE7ccri2EQPvLZeRijYPGqVSeXY,323
|
|
49
|
-
pkgs/argument_parser/argument_parser.py,sha256=
|
|
49
|
+
pkgs/argument_parser/argument_parser.py,sha256=pjphvyGLMA2DC5qqbdiID0SsNvlekWdWtHCfcb7bRbo,26691
|
|
50
50
|
pkgs/argument_parser/case_convert.py,sha256=NuJLJUJRbyVb6_Slen4uqaStEHbcOS1d-hBBfDrrw-c,605
|
|
51
51
|
pkgs/argument_parser/parser_error.py,sha256=2DuYW-vQL4F1V_NEr-WW_ZdBPmH7L_uJiOuv7KhMLXw,2732
|
|
52
52
|
pkgs/filesystem_utils/__init__.py,sha256=Ik9algr3R5KJkMMe-EOBiw22rSvm68yjhYZ7WIKyCQ0,1614
|
|
@@ -55,8 +55,8 @@ pkgs/filesystem_utils/_file_share_session.py,sha256=xlxCbNtOOT1xXCiL2Y_unjWZlQ99
|
|
|
55
55
|
pkgs/filesystem_utils/_gdrive_session.py,sha256=4P2MSsA0GNxIYJxvmf7zKR8dM8oVMCCSzDIEkGA7XqE,11089
|
|
56
56
|
pkgs/filesystem_utils/_local_session.py,sha256=wbmcGqqus417lY_b6VzgEaZA0SUU8Ar5MrgMkXMp58M,2339
|
|
57
57
|
pkgs/filesystem_utils/_s3_session.py,sha256=8SClYopSg4Wgn6EuUZWe8SqO3oaZGzY-Ojj356AsLYg,4503
|
|
58
|
-
pkgs/filesystem_utils/_sftp_session.py,sha256=
|
|
59
|
-
pkgs/filesystem_utils/file_type_utils.py,sha256=
|
|
58
|
+
pkgs/filesystem_utils/_sftp_session.py,sha256=0s9y9IyYwCXZx7hPrifgQciRbNxsfWY7feF7x553lfc,4966
|
|
59
|
+
pkgs/filesystem_utils/file_type_utils.py,sha256=gSZ12rnhjjc0t13_n5nV7NIXLbDj-shF-eUpZTCZtNA,2135
|
|
60
60
|
pkgs/filesystem_utils/filesystem_session.py,sha256=BQ2Go8Mu9-GcnaWh2Pm4x7ugLVsres6XrOQ8RoiEpcE,1045
|
|
61
61
|
pkgs/serialization/__init__.py,sha256=xkCveM7syIh9N5tZ7ojjKKuFrqPwYcH9mu3iFcQ19s4,1213
|
|
62
62
|
pkgs/serialization/annotation.py,sha256=UJNMb9wMUWLWW-om17HSNmfFtAEcZJcCmvirdmmGmhg,2114
|
|
@@ -110,12 +110,12 @@ uncountable/__init__.py,sha256=8l8XWNCKsu7TG94c-xa2KHpDegvxDC2FyQISdWC763Y,89
|
|
|
110
110
|
uncountable/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
111
111
|
uncountable/core/__init__.py,sha256=RFv0kO6rKFf1PtBPu83hCGmxqkJamRtsgQ9_-ztw7tA,341
|
|
112
112
|
uncountable/core/async_batch.py,sha256=9pYGFzVCQXt8059qFHgutweGIFPquJ5Xfq6NT5P-1K0,1206
|
|
113
|
-
uncountable/core/client.py,sha256=
|
|
113
|
+
uncountable/core/client.py,sha256=MYalNgB9SMIq0rqhAw8w43qGrwUPTqGsxlY6x4KgkS8,15160
|
|
114
114
|
uncountable/core/environment.py,sha256=Z9vu7JtnSDgQB_KKcZnjTFNyARXjRr_PDW9krwxNNAo,1132
|
|
115
|
-
uncountable/core/file_upload.py,sha256=
|
|
115
|
+
uncountable/core/file_upload.py,sha256=hvxz6lq1Hv4nK51bux8W_Tl22_UNBtd8U21OWteXWjI,5730
|
|
116
116
|
uncountable/core/types.py,sha256=s2CjqYJpsmbC7xMwxxT7kJ_V9bwokrjjWVVjpMcQpKI,333
|
|
117
117
|
uncountable/core/query/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
118
|
-
uncountable/core/query/builder.py,sha256=
|
|
118
|
+
uncountable/core/query/builder.py,sha256=bnsHdeV6Pe2gf2kpbVDtY8_cQmmp51CMprLfNjymN8Q,8243
|
|
119
119
|
uncountable/core/query/column.py,sha256=Xxvp9C4PkHtcSI5NGAt90NBI4-xpNwpvRJr6f1L51hA,44285
|
|
120
120
|
uncountable/core/query/row.py,sha256=dy68YKvMz336nyOsj_g2oNTLKBuUnKRUz5n99sApfT0,1600
|
|
121
121
|
uncountable/core/query/types.py,sha256=xZgc0_O1PIxZoJWQhxkg3qnSvHj3yt-bv9QX1UCOFGw,481
|
|
@@ -127,20 +127,20 @@ uncountable/integration/entrypoint.py,sha256=BHOYPQgKvZE6HG8Rv15MkdYl8lRkvfDgv1O
|
|
|
127
127
|
uncountable/integration/job.py,sha256=ZVcMddHdOobFHO8MZAPNH3Ht6A8Odu6uEUsqtsKmgtc,8447
|
|
128
128
|
uncountable/integration/request_context.py,sha256=N_FJJxqvfUJ0yV9h3I3vFTGNJiDfyLYObczcYa44pw8,999
|
|
129
129
|
uncountable/integration/scan_profiles.py,sha256=iTpzYKBHarlhYG6CKYtyAmQ7vUhEUbj2icGVHell8AU,3059
|
|
130
|
-
uncountable/integration/scheduler.py,sha256=
|
|
130
|
+
uncountable/integration/scheduler.py,sha256=BajQ4txvgEBw8S9x1P0eGm-uBkKp_oecJK65SQd2hNw,8477
|
|
131
131
|
uncountable/integration/server.py,sha256=P4RRGwU9jMselHPWbU6GxhRLgVtN7Ydcxr18sFn2zI8,5778
|
|
132
|
-
uncountable/integration/telemetry.py,sha256=
|
|
132
|
+
uncountable/integration/telemetry.py,sha256=rWq5DUYldx6vz-L_a3dsohVX8PSJFlBUIo5NfjAYbT4,14986
|
|
133
133
|
uncountable/integration/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
134
134
|
uncountable/integration/db/connect.py,sha256=mE3bdV0huclH2iT_dXCQdRL4LkjIuf_myAR64RTWXEs,498
|
|
135
135
|
uncountable/integration/db/session.py,sha256=96cGQXpe6IugBTdSsjdP0S5yhJ6toSmbVB6qhc3FJzE,693
|
|
136
136
|
uncountable/integration/executors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
137
|
-
uncountable/integration/executors/executors.py,sha256=
|
|
137
|
+
uncountable/integration/executors/executors.py,sha256=E3a0_yrQesfigDzjhUAwD7-l-oc9qnvPh-A8QTK6F3k,5149
|
|
138
138
|
uncountable/integration/executors/generic_upload_executor.py,sha256=BdakXkAvNvLcM96fGvN0Jw2jCvGah6Q29vlXcX1nL-A,12094
|
|
139
139
|
uncountable/integration/executors/script_executor.py,sha256=BBQ9f0l7uH2hgKf60jtm-pONzwk-EeOhM2qBAbv_URo,846
|
|
140
140
|
uncountable/integration/http_server/__init__.py,sha256=WY2HMcL0UCAGYv8y6Pz-j0azbDGXwubFF21EH_zNPkc,189
|
|
141
141
|
uncountable/integration/http_server/types.py,sha256=3JJSulRfv784SbXnXo1Pywto7RwGxgS-iJ2-a6TOnDI,1869
|
|
142
142
|
uncountable/integration/queue_runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
143
|
-
uncountable/integration/queue_runner/job_scheduler.py,sha256=
|
|
143
|
+
uncountable/integration/queue_runner/job_scheduler.py,sha256=LuhJjomXhIy7am-JsdhrF2RxtGd3U4a6mLmIbdqfAPc,9803
|
|
144
144
|
uncountable/integration/queue_runner/queue_runner.py,sha256=N4sUXmlGzVquybiJ7NQZavCJOBGrxBj6k7mb-TITaN0,1139
|
|
145
145
|
uncountable/integration/queue_runner/types.py,sha256=8HS6KnYMS_vc5XHeMpg0BFAQC-5P3QLzd-aDYDMMt3E,244
|
|
146
146
|
uncountable/integration/queue_runner/worker.py,sha256=YU1qRGCYF7vrEcsV4zGnNslYGc6XM9WMCpoATtXB_g0,7314
|
|
@@ -160,8 +160,8 @@ uncountable/integration/queue_runner/datastore/interface.py,sha256=zonEm2O1l5GXE
|
|
|
160
160
|
uncountable/integration/queue_runner/datastore/model.py,sha256=SH0tpXH0G7oydUbOT1z7aFZ6SNIZ6EHc9YAEaM5l1oM,832
|
|
161
161
|
uncountable/integration/secret_retrieval/__init__.py,sha256=3QXVj35w8rRMxVvmmsViFYDi3lcb3g70incfalOEm6o,87
|
|
162
162
|
uncountable/integration/secret_retrieval/retrieve_secret.py,sha256=LBEf18KHtXZxg-ZZ80stJ1vW39AWf0CQllP6pNu3Eq8,2994
|
|
163
|
-
uncountable/integration/webhook_server/entrypoint.py,sha256=
|
|
164
|
-
uncountable/types/__init__.py,sha256=
|
|
163
|
+
uncountable/integration/webhook_server/entrypoint.py,sha256=_1360zLIvEVQVf8ToyK-E2fnaszGKs2HcxcZjNraADc,4268
|
|
164
|
+
uncountable/types/__init__.py,sha256=k3T7TUSXwR7FbNComx3pP66mbc1yxz37OIy_u7ZdOi0,13421
|
|
165
165
|
uncountable/types/async_batch.py,sha256=yCCWrrLQfxXVqZp-KskxLBNkNmuELdz4PJjx8ULppgs,662
|
|
166
166
|
uncountable/types/async_batch_processor.py,sha256=A6ohKoJhUW2jCE8xOUNNt9ab5l6P5jWvWCNBTJPeqQk,46460
|
|
167
167
|
uncountable/types/async_batch_t.py,sha256=9MIXbtMYpHOZW9MkxXb346OfvS5CjuUrBKMd7uyAfyw,4402
|
|
@@ -175,9 +175,11 @@ uncountable/types/calculations.py,sha256=fApOFpgBemt_t7IVneVR0VdI3X5EOxiG6Xhzr6R
|
|
|
175
175
|
uncountable/types/calculations_t.py,sha256=pl-lhjyDQuj11Sf9g1-0BsSkN7Ez8UxDp8-KMQ_3enM,709
|
|
176
176
|
uncountable/types/chemical_structure.py,sha256=ujyragaD26-QG5jgKnWhO7TN3N1V9b_04T2WhqNYxxo,281
|
|
177
177
|
uncountable/types/chemical_structure_t.py,sha256=VFFyits_vx4t5L2euu_qFiSpsGJjURkDPr3ISnr3nPc,855
|
|
178
|
-
uncountable/types/client_base.py,sha256=
|
|
178
|
+
uncountable/types/client_base.py,sha256=ed9pNkxaRBwWdrMMLqcDtqt6-I-GHYZoRzVQvE5IHdU,130243
|
|
179
179
|
uncountable/types/client_config.py,sha256=M7FZ0m_lGmBsIYcMn8pm92DdoVzrLpzd8sH6DqTQLKo,456
|
|
180
180
|
uncountable/types/client_config_t.py,sha256=m1sVg0zaVf8DvQKaDJH_fG1abU2-VZZH0wOIMDjlECU,1944
|
|
181
|
+
uncountable/types/condition_match.py,sha256=ekDzij7-e1PtVwIslSjD1T9fuBIDr5c_7QPdaasiGJw,262
|
|
182
|
+
uncountable/types/condition_match_t.py,sha256=iykByQKFtFa2Gk3sqi9xkqoLHeztRHagV4zkiXqwUh4,536
|
|
181
183
|
uncountable/types/curves.py,sha256=QyEyC20jsG-LGKVx6miiF-w70vKMwNkILFBDIJ5Ok9g,345
|
|
182
184
|
uncountable/types/curves_t.py,sha256=DxYepdC3QKKR7mepOOBoyarNcFZQdUa5ZYH-hwCY3BI,1469
|
|
183
185
|
uncountable/types/data.py,sha256=u2isf4XEug3Eu-xSIoqGaCQmW2dFaKBHCkP_WKYwwBc,500
|
|
@@ -281,7 +283,8 @@ uncountable/types/api/batch/execute_batch_load_async.py,sha256=YLr3Ae3xruoZv3BHL
|
|
|
281
283
|
uncountable/types/api/chemical/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
282
284
|
uncountable/types/api/chemical/convert_chemical_formats.py,sha256=V-s2EMqjodA_zS7-fOdo4iI4yFrvOc2bAwRFCsl445Y,1961
|
|
283
285
|
uncountable/types/api/condition_parameters/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
284
|
-
uncountable/types/api/condition_parameters/upsert_condition_match.py,sha256=
|
|
286
|
+
uncountable/types/api/condition_parameters/upsert_condition_match.py,sha256=VpC3ZNTmP9qxyuoVy6MOnJR1QMH7lnbKmaLpskvbElU,2457
|
|
287
|
+
uncountable/types/api/condition_parameters/upsert_condition_matches.py,sha256=iooN1XX9jqXbS16Tj1iAJ5AglLm5q8J8PJW7SX9Fwuk,6073
|
|
285
288
|
uncountable/types/api/entity/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
286
289
|
uncountable/types/api/entity/create_entities.py,sha256=cCDEra2SHvGWvz7nIxxMDSQN6OWrHMTT0JSomWUesto,1794
|
|
287
290
|
uncountable/types/api/entity/create_entity.py,sha256=urT6C7iGAa7_rCv9Wcz6GM_lKg1tP55E__rjNkj-Rjc,1879
|
|
@@ -395,7 +398,7 @@ uncountable/types/api/uploader/complete_async_parse.py,sha256=ffS3ApqCNkZb6QPuYE
|
|
|
395
398
|
uncountable/types/api/uploader/invoke_uploader.py,sha256=Bj7Dq4A90k00suacwk3bLA_dCb2aovS1kAbVam2AQnM,1395
|
|
396
399
|
uncountable/types/api/user/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
397
400
|
uncountable/types/api/user/get_current_user_info.py,sha256=Avqi_RXtRgbefrT_dwJ9MrO6eDNSSa_Nu650FSuESlg,1109
|
|
398
|
-
uncountablepythonsdk-0.0.
|
|
399
|
-
uncountablepythonsdk-0.0.
|
|
400
|
-
uncountablepythonsdk-0.0.
|
|
401
|
-
uncountablepythonsdk-0.0.
|
|
401
|
+
uncountablepythonsdk-0.0.168.dist-info/METADATA,sha256=Eh2iAbMOCD1M_CLUBemNthcUHEjuZ2DMeTfZeruzGYk,2289
|
|
402
|
+
uncountablepythonsdk-0.0.168.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
403
|
+
uncountablepythonsdk-0.0.168.dist-info/top_level.txt,sha256=1UVGjAU-6hJY9qw2iJ7nCBeEwZ793AEN5ZfKX9A1uj4,31
|
|
404
|
+
uncountablepythonsdk-0.0.168.dist-info/RECORD,,
|
|
File without changes
|
{uncountablepythonsdk-0.0.166.dist-info → uncountablepythonsdk-0.0.168.dist-info}/top_level.txt
RENAMED
|
File without changes
|