hatchet-sdk 1.17.1__py3-none-any.whl → 1.18.0__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/config.py CHANGED
@@ -86,6 +86,7 @@ class ClientConfig(BaseSettings):
86
86
  disable_log_capture: bool = False
87
87
  log_queue_size: int = 1000
88
88
  grpc_enable_fork_support: bool = False
89
+ force_shutdown_on_shutdown_signal: bool = False
89
90
 
90
91
  @model_validator(mode="after")
91
92
  def validate_token_and_tenant(self) -> "ClientConfig":
@@ -0,0 +1,99 @@
1
+ from typing import TYPE_CHECKING, Any, overload
2
+
3
+ from hatchet_sdk.context.context import Context
4
+ from hatchet_sdk.runnables.types import EmptyModel, R, TWorkflowInput
5
+ from hatchet_sdk.runnables.workflow import Standalone, Workflow
6
+
7
+ if TYPE_CHECKING:
8
+ from hatchet_sdk import Hatchet
9
+
10
+
11
+ class StubsClient:
12
+ def __init__(self, client: "Hatchet"):
13
+ self.client = client
14
+
15
+ @overload
16
+ def workflow(
17
+ self,
18
+ *,
19
+ name: str,
20
+ input_validator: None = None,
21
+ ) -> Workflow[EmptyModel]: ...
22
+
23
+ @overload
24
+ def workflow(
25
+ self,
26
+ *,
27
+ name: str,
28
+ input_validator: type[TWorkflowInput],
29
+ ) -> Workflow[TWorkflowInput]: ...
30
+
31
+ def workflow(
32
+ self,
33
+ *,
34
+ name: str,
35
+ input_validator: type[TWorkflowInput] | None = None,
36
+ ) -> Workflow[EmptyModel] | Workflow[TWorkflowInput]:
37
+ return self.client.workflow(name=name, input_validator=input_validator)
38
+
39
+ @overload
40
+ def task(
41
+ self,
42
+ *,
43
+ name: str,
44
+ input_validator: None = None,
45
+ output_validator: None = None,
46
+ ) -> Standalone[EmptyModel, EmptyModel]: ...
47
+
48
+ @overload
49
+ def task(
50
+ self,
51
+ *,
52
+ name: str,
53
+ input_validator: None = None,
54
+ output_validator: type[R],
55
+ ) -> Standalone[EmptyModel, R]: ...
56
+
57
+ @overload
58
+ def task(
59
+ self,
60
+ *,
61
+ name: str,
62
+ input_validator: type[TWorkflowInput],
63
+ output_validator: None = None,
64
+ ) -> Standalone[TWorkflowInput, EmptyModel]: ...
65
+
66
+ @overload
67
+ def task(
68
+ self,
69
+ *,
70
+ name: str,
71
+ input_validator: type[TWorkflowInput],
72
+ output_validator: type[R],
73
+ ) -> Standalone[TWorkflowInput, R]: ...
74
+
75
+ def task(
76
+ self,
77
+ *,
78
+ name: str,
79
+ input_validator: type[TWorkflowInput] | None = None,
80
+ output_validator: type[R] | None = None,
81
+ ) -> (
82
+ Standalone[EmptyModel, R]
83
+ | Standalone[TWorkflowInput, R]
84
+ | Standalone[EmptyModel, EmptyModel]
85
+ | Standalone[TWorkflowInput, EmptyModel]
86
+ ):
87
+ def mock_func(input: Any, ctx: Context) -> Any:
88
+ raise NotImplementedError(
89
+ "This is a stub function and should not be called directly."
90
+ )
91
+
92
+ return_type = output_validator if output_validator is not None else EmptyModel
93
+ mock_func.__annotations__ = {
94
+ "input": Any,
95
+ "ctx": Context,
96
+ "return": return_type,
97
+ }
98
+
99
+ return self.client.task(name=name, input_validator=input_validator)(mock_func)
hatchet_sdk/hatchet.py CHANGED
@@ -20,6 +20,7 @@ from hatchet_sdk.features.metrics import MetricsClient
20
20
  from hatchet_sdk.features.rate_limits import RateLimitsClient
21
21
  from hatchet_sdk.features.runs import RunsClient
22
22
  from hatchet_sdk.features.scheduled import ScheduledClient
23
+ from hatchet_sdk.features.stubs import StubsClient
23
24
  from hatchet_sdk.features.workers import WorkersClient
24
25
  from hatchet_sdk.features.workflows import WorkflowsClient
25
26
  from hatchet_sdk.labels import DesiredWorkerLabel
@@ -156,6 +157,10 @@ class Hatchet:
156
157
  def listener(self) -> RunEventListenerClient:
157
158
  return self._client.listener
158
159
 
160
+ @property
161
+ def stubs(self) -> StubsClient:
162
+ return StubsClient(client=self)
163
+
159
164
  @property
160
165
  def config(self) -> ClientConfig:
161
166
  return self._client.config
@@ -1406,6 +1406,7 @@ class Standalone(BaseWorkflow[TWorkflowInput], Generic[TWorkflowInput, R]):
1406
1406
  parent_outputs: dict[str, JSONSerializableMapping] | None = None,
1407
1407
  retry_count: int = 0,
1408
1408
  lifespan: Any = None,
1409
+ dependencies: dict[str, Any] | None = None,
1409
1410
  ) -> R:
1410
1411
  """
1411
1412
  Mimic the execution of a task. This method is intended to be used to unit test
@@ -1417,6 +1418,7 @@ class Standalone(BaseWorkflow[TWorkflowInput], Generic[TWorkflowInput, R]):
1417
1418
  :param parent_outputs: Outputs from parent tasks, if any. This is useful for mimicking DAG functionality. For instance, if you have a task `step_2` that has a `parent` which is `step_1`, you can pass `parent_outputs={"step_1": {"result": "Hello, world!"}}` to `step_2.mock_run()` to be able to access `ctx.task_output(step_1)` in `step_2`.
1418
1419
  :param retry_count: The number of times the task has been retried.
1419
1420
  :param lifespan: The lifespan to be used in the task, which is useful if one was set on the worker. This will allow you to access `ctx.lifespan` inside of your task.
1421
+ :param dependencies: Dependencies to be injected into the task. This is useful for tasks that have dependencies defined using `Depends`. **IMPORTANT**: You must pass the dependencies _directly_, **not** the `Depends` objects themselves. For example, if you have a task that has a dependency `config: Annotated[str, Depends(get_config)]`, you should pass `dependencies={"config": "config_value"}` to `aio_mock_run`.
1420
1422
 
1421
1423
  :return: The output of the task.
1422
1424
  """
@@ -1427,6 +1429,7 @@ class Standalone(BaseWorkflow[TWorkflowInput], Generic[TWorkflowInput, R]):
1427
1429
  parent_outputs=parent_outputs,
1428
1430
  retry_count=retry_count,
1429
1431
  lifespan=lifespan,
1432
+ dependencies=dependencies,
1430
1433
  )
1431
1434
 
1432
1435
  async def aio_mock_run(
@@ -1436,6 +1439,7 @@ class Standalone(BaseWorkflow[TWorkflowInput], Generic[TWorkflowInput, R]):
1436
1439
  parent_outputs: dict[str, JSONSerializableMapping] | None = None,
1437
1440
  retry_count: int = 0,
1438
1441
  lifespan: Any = None,
1442
+ dependencies: dict[str, Any] | None = None,
1439
1443
  ) -> R:
1440
1444
  """
1441
1445
  Mimic the execution of a task. This method is intended to be used to unit test
@@ -1447,6 +1451,7 @@ class Standalone(BaseWorkflow[TWorkflowInput], Generic[TWorkflowInput, R]):
1447
1451
  :param parent_outputs: Outputs from parent tasks, if any. This is useful for mimicking DAG functionality. For instance, if you have a task `step_2` that has a `parent` which is `step_1`, you can pass `parent_outputs={"step_1": {"result": "Hello, world!"}}` to `step_2.mock_run()` to be able to access `ctx.task_output(step_1)` in `step_2`.
1448
1452
  :param retry_count: The number of times the task has been retried.
1449
1453
  :param lifespan: The lifespan to be used in the task, which is useful if one was set on the worker. This will allow you to access `ctx.lifespan` inside of your task.
1454
+ :param dependencies: Dependencies to be injected into the task. This is useful for tasks that have dependencies defined using `Depends`. **IMPORTANT**: You must pass the dependencies _directly_, **not** the `Depends` objects themselves. For example, if you have a task that has a dependency `config: Annotated[str, Depends(get_config)]`, you should pass `dependencies={"config": "config_value"}` to `aio_mock_run`.
1450
1455
 
1451
1456
  :return: The output of the task.
1452
1457
  """
@@ -1457,6 +1462,7 @@ class Standalone(BaseWorkflow[TWorkflowInput], Generic[TWorkflowInput, R]):
1457
1462
  parent_outputs=parent_outputs,
1458
1463
  retry_count=retry_count,
1459
1464
  lifespan=lifespan,
1465
+ dependencies=dependencies,
1460
1466
  )
1461
1467
 
1462
1468
  @property
@@ -405,8 +405,22 @@ class Worker:
405
405
  logger.exception("error checking listener health")
406
406
 
407
407
  def _setup_signal_handlers(self) -> None:
408
- signal.signal(signal.SIGTERM, self._handle_exit_signal)
409
- signal.signal(signal.SIGINT, self._handle_exit_signal)
408
+ signal.signal(
409
+ signal.SIGTERM,
410
+ (
411
+ self._handle_force_quit_signal
412
+ if self.config.force_shutdown_on_shutdown_signal
413
+ else self._handle_exit_signal
414
+ ),
415
+ )
416
+ signal.signal(
417
+ signal.SIGINT,
418
+ (
419
+ self._handle_force_quit_signal
420
+ if self.config.force_shutdown_on_shutdown_signal
421
+ else self._handle_exit_signal
422
+ ),
423
+ )
410
424
  signal.signal(signal.SIGQUIT, self._handle_force_quit_signal)
411
425
 
412
426
  def _handle_exit_signal(self, signum: int, frame: FrameType | None) -> None:
@@ -416,7 +430,8 @@ class Worker:
416
430
  self.loop.create_task(self.exit_gracefully())
417
431
 
418
432
  def _handle_force_quit_signal(self, signum: int, frame: FrameType | None) -> None:
419
- logger.info("received SIGQUIT...")
433
+ signal_received = signal.Signals(signum).name
434
+ logger.info(f"received {signal_received}...")
420
435
  if self.loop:
421
436
  self.loop.create_task(self._exit_forcefully())
422
437
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hatchet-sdk
3
- Version: 1.17.1
3
+ Version: 1.18.0
4
4
  Summary:
5
5
  License: MIT
6
6
  Author: Alexander Belanger
@@ -12,9 +12,9 @@ Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
14
  Provides-Extra: otel
15
+ Provides-Extra: v0
15
16
  Requires-Dist: aiohttp (>=3.10.5,<4.0.0)
16
- Requires-Dist: aiohttp-retry (>=2.8.3,<3.0.0)
17
- Requires-Dist: aiostream (>=0.5.2,<0.6.0)
17
+ Requires-Dist: cel-python (>=0.4.0,<0.5.0) ; extra == "v0"
18
18
  Requires-Dist: grpcio (>=1.64.1,!=1.68.*) ; python_version < "3.13"
19
19
  Requires-Dist: grpcio (>=1.69.0) ; python_version >= "3.13"
20
20
  Requires-Dist: grpcio-tools (>=1.64.1,!=1.68.*) ; python_version < "3.13"
@@ -258,7 +258,7 @@ hatchet_sdk/clients/rest/rest.py,sha256=zZHTzgl-NBdcK6XhG23m_s9RKRONGPPItzGe407s
258
258
  hatchet_sdk/clients/rest/tenacity_utils.py,sha256=WeNt_1ah2-NKB9qTI3JnTjItpSviBV95U0cPM4kB5as,1211
259
259
  hatchet_sdk/clients/v1/api_client.py,sha256=vUaQr7Xi71a2kFHkZy-pB3tCg3-t0ROlqbPUQA6skIA,2013
260
260
  hatchet_sdk/conditions.py,sha256=CnhpkXgVXM3wc0kAX8KZQA6tp8NFAbdzAN2xFbw7Hb0,4522
261
- hatchet_sdk/config.py,sha256=4tYuNXuzHAhapNveNA4DYpvtQERDoefrIn0qfwImqkc,5297
261
+ hatchet_sdk/config.py,sha256=QVHFVPmqNxc7PFb2Mvll1BGDEmIo9h587N44W7KoYxE,5349
262
262
  hatchet_sdk/connection.py,sha256=XCBY9-UxaN3blakgZ59AhDpjb1ilLOOlmNNM6QaDtMM,2961
263
263
  hatchet_sdk/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
264
264
  hatchet_sdk/context/context.py,sha256=KE-GsaosBar8USXSj1lkWHdsZXfXFf6tI9RwGTOF-aM,16278
@@ -290,10 +290,11 @@ hatchet_sdk/features/metrics.py,sha256=do4kVX6cjDszHocc-IoS8BdT5ChptPc39oElbW6Cd
290
290
  hatchet_sdk/features/rate_limits.py,sha256=eh55Z3w75cYUthqTyoWmNxj_6tN3rjebMKm3of-vxv0,2155
291
291
  hatchet_sdk/features/runs.py,sha256=u0KEcLOLSWusgyp8T4z30yR9UxSdz9CdyrGxM9SSr-g,23758
292
292
  hatchet_sdk/features/scheduled.py,sha256=t7YA9CoJrzBhH82ChTSFWaTF_dyoC9i1O_wf9ywsphc,8939
293
+ hatchet_sdk/features/stubs.py,sha256=5NF43cgZKzh7qzYv_lLae4Xkh_zrz2wMj8M_OoTAAF8,2604
293
294
  hatchet_sdk/features/tenant.py,sha256=xkhh5mRKCWbunk_S1iBmGR-DYR-F4mjxk8jLyYUyzNE,886
294
295
  hatchet_sdk/features/workers.py,sha256=DVdno28RmtlfhMJUkaPcOMHNKXCPV0RFrXtLqV6zWyE,2600
295
296
  hatchet_sdk/features/workflows.py,sha256=WTt58imAFRrEEB3M5hEEIBwNtrzdWbITFpgtsIqJNSM,4770
296
- hatchet_sdk/hatchet.py,sha256=rEqakbTENR__bars1GM42d6RWrsgu8YzenvnEnkEd5E,26416
297
+ hatchet_sdk/hatchet.py,sha256=v4V7_jHy5cYYFGM2nvrjmuu979i59KuDDRZZUyW8Eis,26558
297
298
  hatchet_sdk/labels.py,sha256=nATgxWE3lFxRTnfISEpoIRLGbMfAZsHF4lZTuG4Mfic,182
298
299
  hatchet_sdk/logger.py,sha256=5uOr52T4mImSQm1QvWT8HvZFK5WfPNh3Y1cBQZRFgUQ,333
299
300
  hatchet_sdk/metadata.py,sha256=XkRbhnghJJGCdVvF-uzyGBcNaTqpeQ3uiQvNNP1wyBc,107
@@ -304,7 +305,7 @@ hatchet_sdk/runnables/action.py,sha256=zrVHpyzIQ9XZgWwY69b_6uhZd53An4trRoLd9b3os
304
305
  hatchet_sdk/runnables/contextvars.py,sha256=jHrrewUlFPAT9f2u3VCsuSlDBtBoagEUtUzJOSmm4yk,1118
305
306
  hatchet_sdk/runnables/task.py,sha256=JsiDBkYQVJodyqtNDT9z8Pwz3ePL8GhY0Z1-ptPw9ms,16030
306
307
  hatchet_sdk/runnables/types.py,sha256=M23xSMTBPl12CXCCXZ0wbnqZ_sePB6CJKtOdipiNDlg,4362
307
- hatchet_sdk/runnables/workflow.py,sha256=Nm71LrY_EcPJUrlzRuBh6sp7bv-pMrt0gQgZNftue9g,57848
308
+ hatchet_sdk/runnables/workflow.py,sha256=-oz0q76N-NAi3Xon1VXkzDvZe0ZjbXR_O-3sTCGfokk,58876
308
309
  hatchet_sdk/token.py,sha256=KjIiInwG5Kqd_FO4BSW1x_5Uc7PFbnzIVJqr50-ZldE,779
309
310
  hatchet_sdk/utils/aio.py,sha256=cu1rD_UZkShtfzi7iXMYwBBaCRdxJQTdUC0_mf8nU2E,499
310
311
  hatchet_sdk/utils/backoff.py,sha256=6B5Rb5nLKw_TqqgpJMYjIBV1PTTtbOMRZCveisVhg_I,353
@@ -540,9 +541,9 @@ hatchet_sdk/worker/action_listener_process.py,sha256=CzXen-7tFG_rryvM2xWV2_KMUFC
540
541
  hatchet_sdk/worker/runner/run_loop_manager.py,sha256=BcdfxSvZdrxbeTZSUASwCTMKJe6pwLorHVKPTprkM2k,4176
541
542
  hatchet_sdk/worker/runner/runner.py,sha256=QULD00hEyW2dcHCcH46C1k7mxr5nHEwtusyAs33VOO0,22857
542
543
  hatchet_sdk/worker/runner/utils/capture_logs.py,sha256=hNELuNHS0HmoMZJ7F7yIjZuahPEx9cOx9JZro618W74,4675
543
- hatchet_sdk/worker/worker.py,sha256=9EiESMMcS7voa4cAnmnHMx4rC-pqaTmP74bcTbFPqfQ,16435
544
+ hatchet_sdk/worker/worker.py,sha256=BP8A70hQxNvJ8VG8Osb5NTE4mwdcmEkiLwdtwkkNbuE,16868
544
545
  hatchet_sdk/workflow_run.py,sha256=KcylcqRwKADtnzOTjoiVr1vdr7qTZFtDeD5aRS6A4Y8,2823
545
- hatchet_sdk-1.17.1.dist-info/METADATA,sha256=Jq0SedvsRiVyJAhdF8JN_vyc-LjfOTeh-xJvC1MnNsM,3585
546
- hatchet_sdk-1.17.1.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
547
- hatchet_sdk-1.17.1.dist-info/entry_points.txt,sha256=Un_76pcLse-ZGBlwebhQpnTPyQrripeHW8J7qmEpGOk,1400
548
- hatchet_sdk-1.17.1.dist-info/RECORD,,
546
+ hatchet_sdk-1.18.0.dist-info/METADATA,sha256=tRyt8eMKJTTZlPu_Hp0nhrvabcnRywZjMLjAcxTh_Js,3575
547
+ hatchet_sdk-1.18.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
548
+ hatchet_sdk-1.18.0.dist-info/entry_points.txt,sha256=Un_76pcLse-ZGBlwebhQpnTPyQrripeHW8J7qmEpGOk,1400
549
+ hatchet_sdk-1.18.0.dist-info/RECORD,,