UncountablePythonSDK 0.0.166__py3-none-any.whl → 0.0.167__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
- 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
- {uncountablepythonsdk-0.0.166.dist-info → uncountablepythonsdk-0.0.167.dist-info}/METADATA +1 -1
- {uncountablepythonsdk-0.0.166.dist-info → uncountablepythonsdk-0.0.167.dist-info}/RECORD +13 -13
- {uncountablepythonsdk-0.0.166.dist-info → uncountablepythonsdk-0.0.167.dist-info}/WHEEL +0 -0
- {uncountablepythonsdk-0.0.166.dist-info → uncountablepythonsdk-0.0.167.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))
|
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:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: UncountablePythonSDK
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.167
|
|
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
|
|
@@ -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,7 +160,7 @@ 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=
|
|
163
|
+
uncountable/integration/webhook_server/entrypoint.py,sha256=_1360zLIvEVQVf8ToyK-E2fnaszGKs2HcxcZjNraADc,4268
|
|
164
164
|
uncountable/types/__init__.py,sha256=nOt7Bnspaz_A1XILTyUt9QG8JN9Wj6K67lAD_CtzPMY,13216
|
|
165
165
|
uncountable/types/async_batch.py,sha256=yCCWrrLQfxXVqZp-KskxLBNkNmuELdz4PJjx8ULppgs,662
|
|
166
166
|
uncountable/types/async_batch_processor.py,sha256=A6ohKoJhUW2jCE8xOUNNt9ab5l6P5jWvWCNBTJPeqQk,46460
|
|
@@ -395,7 +395,7 @@ uncountable/types/api/uploader/complete_async_parse.py,sha256=ffS3ApqCNkZb6QPuYE
|
|
|
395
395
|
uncountable/types/api/uploader/invoke_uploader.py,sha256=Bj7Dq4A90k00suacwk3bLA_dCb2aovS1kAbVam2AQnM,1395
|
|
396
396
|
uncountable/types/api/user/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
397
397
|
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.
|
|
398
|
+
uncountablepythonsdk-0.0.167.dist-info/METADATA,sha256=9eJI6d7bfSrVsfgb7zkpYakuFgzQfg5SIXekqr9cbcc,2289
|
|
399
|
+
uncountablepythonsdk-0.0.167.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
400
|
+
uncountablepythonsdk-0.0.167.dist-info/top_level.txt,sha256=1UVGjAU-6hJY9qw2iJ7nCBeEwZ793AEN5ZfKX9A1uj4,31
|
|
401
|
+
uncountablepythonsdk-0.0.167.dist-info/RECORD,,
|
|
File without changes
|
{uncountablepythonsdk-0.0.166.dist-info → uncountablepythonsdk-0.0.167.dist-info}/top_level.txt
RENAMED
|
File without changes
|