hatchet-sdk 1.14.2__py3-none-any.whl → 1.14.3__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 hatchet-sdk might be problematic. Click here for more details.
- hatchet_sdk/__init__.py +3 -1
- hatchet_sdk/utils/serde.py +52 -0
- hatchet_sdk/worker/runner/runner.py +32 -10
- {hatchet_sdk-1.14.2.dist-info → hatchet_sdk-1.14.3.dist-info}/METADATA +1 -1
- {hatchet_sdk-1.14.2.dist-info → hatchet_sdk-1.14.3.dist-info}/RECORD +7 -6
- {hatchet_sdk-1.14.2.dist-info → hatchet_sdk-1.14.3.dist-info}/WHEEL +0 -0
- {hatchet_sdk-1.14.2.dist-info → hatchet_sdk-1.14.3.dist-info}/entry_points.txt +0 -0
hatchet_sdk/__init__.py
CHANGED
|
@@ -11,9 +11,9 @@ from hatchet_sdk.clients.listeners.run_event_listener import (
|
|
|
11
11
|
StepRunEventType,
|
|
12
12
|
WorkflowRunEventType,
|
|
13
13
|
)
|
|
14
|
-
from hatchet_sdk.clients.rest.models.accept_invite_request import AcceptInviteRequest
|
|
15
14
|
|
|
16
15
|
# import models into sdk package
|
|
16
|
+
from hatchet_sdk.clients.rest.models.accept_invite_request import AcceptInviteRequest
|
|
17
17
|
from hatchet_sdk.clients.rest.models.api_error import APIError
|
|
18
18
|
from hatchet_sdk.clients.rest.models.api_errors import APIErrors
|
|
19
19
|
from hatchet_sdk.clients.rest.models.api_meta import APIMeta
|
|
@@ -166,6 +166,7 @@ from hatchet_sdk.runnables.types import (
|
|
|
166
166
|
)
|
|
167
167
|
from hatchet_sdk.runnables.workflow import TaskRunRef
|
|
168
168
|
from hatchet_sdk.utils.opentelemetry import OTelAttribute
|
|
169
|
+
from hatchet_sdk.utils.serde import remove_null_unicode_character
|
|
169
170
|
from hatchet_sdk.worker.worker import Worker, WorkerStartOptions, WorkerStatus
|
|
170
171
|
from hatchet_sdk.workflow_run import WorkflowRunRef
|
|
171
172
|
|
|
@@ -290,5 +291,6 @@ __all__ = [
|
|
|
290
291
|
"WorkflowVersionDefinition",
|
|
291
292
|
"WorkflowVersionMeta",
|
|
292
293
|
"or_",
|
|
294
|
+
"remove_null_unicode_character",
|
|
293
295
|
"workflow",
|
|
294
296
|
]
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from typing import Any, TypeVar, cast, overload
|
|
2
|
+
|
|
3
|
+
T = TypeVar("T")
|
|
4
|
+
K = TypeVar("K")
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@overload
|
|
8
|
+
def remove_null_unicode_character(data: str) -> str: ...
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@overload
|
|
12
|
+
def remove_null_unicode_character(data: dict[K, T]) -> dict[K, T]: ...
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@overload
|
|
16
|
+
def remove_null_unicode_character(data: list[T]) -> list[T]: ...
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@overload
|
|
20
|
+
def remove_null_unicode_character(data: tuple[T, ...]) -> tuple[T, ...]: ...
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def remove_null_unicode_character(
|
|
24
|
+
data: str | dict[K, T] | list[T] | tuple[T, ...],
|
|
25
|
+
) -> str | dict[K, T] | list[T] | tuple[T, ...]:
|
|
26
|
+
"""
|
|
27
|
+
Recursively traverse a dictionary (a task's output) and remove the unicode escape sequence \\u0000 which will cause unexpected behavior in Hatchet.
|
|
28
|
+
|
|
29
|
+
Needed as Hatchet does not support \\u0000 in task outputs
|
|
30
|
+
|
|
31
|
+
:param data: The task output (a JSON-serializable dictionary or mapping)
|
|
32
|
+
:return: The same dictionary with all \\u0000 characters removed from strings, and nested dictionaries/lists processed recursively.
|
|
33
|
+
:raises TypeError: If the input is not a string, dictionary, list, or tuple.
|
|
34
|
+
"""
|
|
35
|
+
if isinstance(data, str):
|
|
36
|
+
return data.replace("\u0000", "")
|
|
37
|
+
|
|
38
|
+
if isinstance(data, dict):
|
|
39
|
+
return {
|
|
40
|
+
key: remove_null_unicode_character(cast(Any, value))
|
|
41
|
+
for key, value in data.items()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if isinstance(data, list):
|
|
45
|
+
return [remove_null_unicode_character(cast(Any, item)) for item in data]
|
|
46
|
+
|
|
47
|
+
if isinstance(data, tuple):
|
|
48
|
+
return tuple(remove_null_unicode_character(cast(Any, item)) for item in data)
|
|
49
|
+
|
|
50
|
+
raise TypeError(
|
|
51
|
+
f"Unsupported type {type(data)}. Expected str, dict, list, or tuple."
|
|
52
|
+
)
|
|
@@ -4,9 +4,9 @@ import functools
|
|
|
4
4
|
import json
|
|
5
5
|
from collections.abc import Callable
|
|
6
6
|
from concurrent.futures import ThreadPoolExecutor
|
|
7
|
-
from contextlib import suppress
|
|
8
7
|
from enum import Enum
|
|
9
8
|
from multiprocessing import Queue
|
|
9
|
+
from textwrap import dedent
|
|
10
10
|
from threading import Thread, current_thread
|
|
11
11
|
from typing import Any, Literal, cast, overload
|
|
12
12
|
|
|
@@ -49,6 +49,7 @@ from hatchet_sdk.runnables.contextvars import (
|
|
|
49
49
|
)
|
|
50
50
|
from hatchet_sdk.runnables.task import Task
|
|
51
51
|
from hatchet_sdk.runnables.types import R, TWorkflowInput
|
|
52
|
+
from hatchet_sdk.utils.serde import remove_null_unicode_character
|
|
52
53
|
from hatchet_sdk.worker.action_listener_process import ActionEvent
|
|
53
54
|
from hatchet_sdk.worker.runner.utils.capture_logs import (
|
|
54
55
|
AsyncLogSender,
|
|
@@ -410,7 +411,7 @@ class Runner:
|
|
|
410
411
|
)
|
|
411
412
|
|
|
412
413
|
## IMPORTANT: Keep this method's signature in sync with the wrapper in the OTel instrumentor
|
|
413
|
-
async def handle_start_step_run(self, action: Action) -> None:
|
|
414
|
+
async def handle_start_step_run(self, action: Action) -> Exception | None:
|
|
414
415
|
action_name = action.action_id
|
|
415
416
|
|
|
416
417
|
# Find the corresponding action function from the registry
|
|
@@ -444,8 +445,11 @@ class Runner:
|
|
|
444
445
|
|
|
445
446
|
## FIXME: Handle cancelled exceptions and other special exceptions
|
|
446
447
|
## that we don't want to suppress here
|
|
447
|
-
|
|
448
|
+
try:
|
|
448
449
|
await task
|
|
450
|
+
except Exception as e:
|
|
451
|
+
## Used for the OTel instrumentor to capture exceptions
|
|
452
|
+
return e
|
|
449
453
|
|
|
450
454
|
## Once the step run completes, we need to remove the workflow spawn index
|
|
451
455
|
## so we don't leak memory
|
|
@@ -453,6 +457,8 @@ class Runner:
|
|
|
453
457
|
async with spawn_index_lock:
|
|
454
458
|
workflow_spawn_indices.pop(action.key)
|
|
455
459
|
|
|
460
|
+
return None
|
|
461
|
+
|
|
456
462
|
## IMPORTANT: Keep this method's signature in sync with the wrapper in the OTel instrumentor
|
|
457
463
|
async def handle_start_group_key_run(self, action: Action) -> Exception | None:
|
|
458
464
|
action_name = action.action_id
|
|
@@ -557,14 +563,30 @@ class Runner:
|
|
|
557
563
|
f"Tasks must return either a dictionary or a Pydantic BaseModel which can be serialized to a JSON object. Got object of type {type(output)} instead."
|
|
558
564
|
)
|
|
559
565
|
|
|
560
|
-
if output is
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
+
if output is None:
|
|
567
|
+
return ""
|
|
568
|
+
|
|
569
|
+
try:
|
|
570
|
+
serialized_output = json.dumps(output, default=str)
|
|
571
|
+
except Exception as e:
|
|
572
|
+
logger.error(f"Could not serialize output: {e}")
|
|
573
|
+
serialized_output = str(output)
|
|
574
|
+
|
|
575
|
+
if "\\u0000" in serialized_output:
|
|
576
|
+
raise IllegalTaskOutputError(
|
|
577
|
+
dedent(
|
|
578
|
+
f"""
|
|
579
|
+
Task outputs cannot contain the unicode null character \\u0000
|
|
580
|
+
|
|
581
|
+
Please see this Discord thread: https://discord.com/channels/1088927970518909068/1384324576166678710/1386714014565928992
|
|
582
|
+
Relevant Postgres documentation: https://www.postgresql.org/docs/current/datatype-json.html
|
|
583
|
+
|
|
584
|
+
Use `hatchet_sdk.{remove_null_unicode_character.__name__}` to sanitize your output if you'd like to remove the character.
|
|
585
|
+
"""
|
|
586
|
+
)
|
|
587
|
+
)
|
|
566
588
|
|
|
567
|
-
return
|
|
589
|
+
return serialized_output
|
|
568
590
|
|
|
569
591
|
async def wait_for_tasks(self) -> None:
|
|
570
592
|
running = len(self.tasks.keys())
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
hatchet_sdk/__init__.py,sha256=
|
|
1
|
+
hatchet_sdk/__init__.py,sha256=LdT8xJ7-95gwksRZuCzuKDM5bfLx8uW8gXGPL7VMqwc,10743
|
|
2
2
|
hatchet_sdk/client.py,sha256=OXb2hOJ5p7pY5QMlM4cydb4aGyf6bDdbyWQjPMVCe64,2413
|
|
3
3
|
hatchet_sdk/clients/admin.py,sha256=t8GXhjMiFp9iL0ofISNxSOKlfwaOTX2iQbZfz1G0pHU,16936
|
|
4
4
|
hatchet_sdk/clients/dispatcher/action_listener.py,sha256=tFknXH9iSP0OFYYVcKeDZVrcDNIz00ZQVTxSbHpbKhI,13863
|
|
@@ -283,6 +283,7 @@ hatchet_sdk/utils/backoff.py,sha256=6B5Rb5nLKw_TqqgpJMYjIBV1PTTtbOMRZCveisVhg_I,
|
|
|
283
283
|
hatchet_sdk/utils/datetimes.py,sha256=vIZNEX8tt-bknaIuTmoLEmKVt18dBjClH3urYtCJAys,775
|
|
284
284
|
hatchet_sdk/utils/opentelemetry.py,sha256=64TVwCLrUzEmcL2BUNPV_QubfiR5jajOZtVeGYLnEEA,1226
|
|
285
285
|
hatchet_sdk/utils/proto_enums.py,sha256=v2gp_ZmIhPxURVXwz5lscllXwZXDl5XGXeL6gezw3o0,1241
|
|
286
|
+
hatchet_sdk/utils/serde.py,sha256=d2iypdK2UQCPA19NgYa0Tr7CTbk25KPbaCMqcqN3CYk,1645
|
|
286
287
|
hatchet_sdk/utils/timedelta_to_expression.py,sha256=YujnBnGn7lxtkUdKIeqmOiN_ZCGBpRPjCCSzcD3jxzA,644
|
|
287
288
|
hatchet_sdk/utils/typing.py,sha256=FgYnZyJSoRjNVFodxlI9gn0X8ST1KFed7xfUynIxa2U,978
|
|
288
289
|
hatchet_sdk/v0/__init__.py,sha256=r3Q7l2RsLgdIkK2jjiz7-JJpD1T_Zy--Oa9MN5n_yEs,9654
|
|
@@ -509,11 +510,11 @@ hatchet_sdk/v0/workflow_run.py,sha256=jsEZprXshrSV7i_TtL5uoCL03D18zQ3NeJCq7mp97D
|
|
|
509
510
|
hatchet_sdk/worker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
510
511
|
hatchet_sdk/worker/action_listener_process.py,sha256=Xzzn1dDFJrqnC9HBsh3fYI8lfpOD4Ecze47qmm_XUWE,12923
|
|
511
512
|
hatchet_sdk/worker/runner/run_loop_manager.py,sha256=GeILClNXaDbsjXCQb0bBdgeyAwZGem2JdaH0t6wz__I,4053
|
|
512
|
-
hatchet_sdk/worker/runner/runner.py,sha256=
|
|
513
|
+
hatchet_sdk/worker/runner/runner.py,sha256=Btz7wd0DQ-5aPEZLN3T5X5__8DjuxN6H4yQEVX0eZiI,21678
|
|
513
514
|
hatchet_sdk/worker/runner/utils/capture_logs.py,sha256=DKw6boqVsSCM1XvBWYuc833MZxCdSpMxg3l4aAqKPyw,3465
|
|
514
515
|
hatchet_sdk/worker/worker.py,sha256=nDuRo_LishRuOCTnDonc7G7qeOoW93nRHGd-fQOE_bs,16541
|
|
515
516
|
hatchet_sdk/workflow_run.py,sha256=KcylcqRwKADtnzOTjoiVr1vdr7qTZFtDeD5aRS6A4Y8,2823
|
|
516
|
-
hatchet_sdk-1.14.
|
|
517
|
-
hatchet_sdk-1.14.
|
|
518
|
-
hatchet_sdk-1.14.
|
|
519
|
-
hatchet_sdk-1.14.
|
|
517
|
+
hatchet_sdk-1.14.3.dist-info/METADATA,sha256=3D-GMkNjhRG37vaE8W4lXoG1MMu_2MpnKcAwK5elTkY,3636
|
|
518
|
+
hatchet_sdk-1.14.3.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
519
|
+
hatchet_sdk-1.14.3.dist-info/entry_points.txt,sha256=Un_76pcLse-ZGBlwebhQpnTPyQrripeHW8J7qmEpGOk,1400
|
|
520
|
+
hatchet_sdk-1.14.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|