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.
@@ -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
- return lambda value: origin(
430
- (key_parser(k), v_parser(v)) for k, v in value.items()
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))
@@ -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.log_info(api_request.endpoint, attributes=attributes)
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
@@ -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.log_info("Uploading file", attributes=attributes)
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
- _ASYNC_EXPORT_TIMEOUT_SECONDS = 60 * 10
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, offset: int = 0) -> list[QueryRowT]:
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) < 100:
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
- def _await_async_export(self) -> list[QueryRowT]:
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("Listing export failed to create async job")
158
-
159
- status_query = QueryBuilder(client=self._client, model=_AsyncExportJob)
160
-
161
- start_time = time.time()
162
- while time.time() - start_time < _ASYNC_EXPORT_TIMEOUT_SECONDS:
163
- match (
164
- status_query
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
- case async_jobs_t.AsyncJobStatus.COMPLETED:
170
- export_file = self._client.download_files(
171
- file_query=FileDownloadQueryEntityField(
172
- entity=entity_t.EntityIdentifier(
173
- identifier_key=identifier_t.IdentifierKeyId(
174
- id=async_job_entity.id
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
- )[0].data.read()
183
-
184
- return [
185
- self._parse_row(row.column_values)
186
- for row in CachedParser(list_entities_t.Data)
187
- .parse_api(
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.log_info(f"Starting job: `{job_location}`")
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.log_info(
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.log_info(
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.log_info(
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.log_info("Vaccuuming queued jobs...")
204
+ logger.log_debug("Vaccuuming queued jobs...")
205
205
  deleted_uuids = datastore.vaccuum_queued_jobs()
206
206
 
207
- logger.log_info(
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.log_info("received shutdown command, shutting down sub-processes")
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.log_info(
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.log_info(f"{proc_info.name} shut down successfully")
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.log_info("queue runner restarted successfully")
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.log_info("cron server restarted successfully")
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.log_info("uwsgi restarted successfully")
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.log_info(f"started process {process.name}")
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.log_info(
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.log_info("Job resource usage summary", attributes=stats)
323
+ self.logger.log_debug("Job resource usage summary", attributes=stats)
314
324
  return
315
325
 
316
326
  def summary(self) -> Attributes:
@@ -91,7 +91,7 @@ def register_route(
91
91
  methods=["POST"],
92
92
  )
93
93
 
94
- server_logger.log_info(
94
+ server_logger.log_debug(
95
95
  f"job {job.id} webhook registered at: {route}", attributes=log_attributes
96
96
  )
97
97
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: UncountablePythonSDK
3
- Version: 0.0.166
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=3qUDflMdtgC7cDZljo3-eSpikVqhT8WVb1nhul8Q_v8,26638
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=DRb2LUacLQaxwQu7YPMK4DHQd68K3CGswa8hF3D2Lac,15159
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=oIhtUvVfbI7mJO6DaP2aHltv1DD_XV_pOnxyj3wtoLE,5729
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=Wv7KaU5n6HmN59kg7Ut-yLOBeJpvw_csMrNVwJFBOuA,7523
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=4fLxzSwmuZ0FafM3HmiThFFxfZKG9WlcQCG4fT6yyXM,8470
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=BvbL7pM_OX02UUX4gpxk-eMEEUHIqlRx9FZ2V12USPQ,14530
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=NWe9KjJL9C76h77sutzoqhI8HkdBkLUjLrhRUmC3bpU,5147
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=RWWDADzLFoTVVIAFqSzDedh8Kcpz9ChamEnjCZZa6Aw,9799
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=TeHkpufKsbklbHXCXz57Hvh887jNOD8LV7p8x-9LE5k,4267
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.166.dist-info/METADATA,sha256=E-holHf_W4PtrzbwUMmVB-6mJ-3xaKNhUs7sZSAzJ4I,2289
399
- uncountablepythonsdk-0.0.166.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
400
- uncountablepythonsdk-0.0.166.dist-info/top_level.txt,sha256=1UVGjAU-6hJY9qw2iJ7nCBeEwZ793AEN5ZfKX9A1uj4,31
401
- uncountablepythonsdk-0.0.166.dist-info/RECORD,,
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,,