hatchet-sdk 0.42.5__py3-none-any.whl → 0.43.1__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/hatchet.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
  import logging
3
- from typing import Any, Callable, Optional, Type, TypeVar, Union
3
+ from typing import Any, Callable, Optional, ParamSpec, Type, TypeVar, Union
4
4
 
5
5
  from pydantic import BaseModel
6
6
  from typing_extensions import deprecated
@@ -35,6 +35,9 @@ from .workflow import (
35
35
  )
36
36
 
37
37
  T = TypeVar("T", bound=BaseModel)
38
+ R = TypeVar("R")
39
+ P = ParamSpec("P")
40
+
38
41
  TWorkflow = TypeVar("TWorkflow", bound=object)
39
42
 
40
43
 
@@ -87,10 +90,10 @@ def step(
87
90
  desired_worker_labels: dict[str, DesiredWorkerLabel] = {},
88
91
  backoff_factor: float | None = None,
89
92
  backoff_max_seconds: int | None = None,
90
- ) -> Callable[..., Any]:
93
+ ) -> Callable[[Callable[P, R]], Callable[P, R]]:
91
94
  parents = parents or []
92
95
 
93
- def inner(func: Callable[[Context], Any]) -> Callable[[Context], Any]:
96
+ def inner(func: Callable[P, R]) -> Callable[P, R]:
94
97
  limits = None
95
98
  if rate_limits:
96
99
  limits = [rate_limit._req for rate_limit in rate_limits or []]
@@ -99,7 +102,6 @@ def step(
99
102
  setattr(func, "_step_parents", parents)
100
103
  setattr(func, "_step_timeout", timeout)
101
104
  setattr(func, "_step_retries", retries)
102
- setattr(func, "_step_rate_limits", retries)
103
105
  setattr(func, "_step_rate_limits", limits)
104
106
  setattr(func, "_step_backoff_factor", backoff_factor)
105
107
  setattr(func, "_step_backoff_max_seconds", backoff_max_seconds)
hatchet_sdk/loader.py CHANGED
@@ -43,6 +43,8 @@ class ClientConfig:
43
43
  otel_service_name: str | None = None,
44
44
  otel_exporter_oltp_headers: dict[str, str] | None = None,
45
45
  otel_exporter_oltp_protocol: str | None = None,
46
+ worker_healthcheck_port: int | None = None,
47
+ worker_healthcheck_enabled: bool | None = None,
46
48
  ):
47
49
  self.tenant_id = tenant_id
48
50
  self.tls_config = tls_config
@@ -57,6 +59,8 @@ class ClientConfig:
57
59
  self.otel_service_name = otel_service_name
58
60
  self.otel_exporter_oltp_headers = otel_exporter_oltp_headers
59
61
  self.otel_exporter_oltp_protocol = otel_exporter_oltp_protocol
62
+ self.worker_healthcheck_port = worker_healthcheck_port
63
+ self.worker_healthcheck_enabled = worker_healthcheck_enabled
60
64
 
61
65
  if not self.logInterceptor:
62
66
  self.logInterceptor = getLogger()
@@ -163,6 +167,23 @@ class ConfigLoader:
163
167
  "otel_exporter_oltp_protocol", "HATCHET_CLIENT_OTEL_EXPORTER_OTLP_PROTOCOL"
164
168
  )
165
169
 
170
+ worker_healthcheck_port = int(
171
+ get_config_value(
172
+ "worker_healthcheck_port", "HATCHET_CLIENT_WORKER_HEALTHCHECK_PORT"
173
+ )
174
+ or 8001
175
+ )
176
+
177
+ worker_healthcheck_enabled = (
178
+ str(
179
+ get_config_value(
180
+ "worker_healthcheck_port",
181
+ "HATCHET_CLIENT_WORKER_HEALTHCHECK_ENABLED",
182
+ )
183
+ )
184
+ == "True"
185
+ )
186
+
166
187
  return ClientConfig(
167
188
  tenant_id=tenant_id,
168
189
  tls_config=tls_config,
@@ -178,6 +199,8 @@ class ConfigLoader:
178
199
  otel_service_name=otel_service_name,
179
200
  otel_exporter_oltp_headers=otel_exporter_oltp_headers,
180
201
  otel_exporter_oltp_protocol=otel_exporter_oltp_protocol,
202
+ worker_healthcheck_port=worker_healthcheck_port,
203
+ worker_healthcheck_enabled=worker_healthcheck_enabled,
181
204
  )
182
205
 
183
206
  def _load_tls_config(self, tls_data: Dict, host_port) -> ClientTLSConfig:
hatchet_sdk/py.typed ADDED
File without changes
@@ -12,7 +12,10 @@ from multiprocessing.process import BaseProcess
12
12
  from types import FrameType
13
13
  from typing import Any, Callable, TypeVar, get_type_hints
14
14
 
15
- from pydantic import BaseModel
15
+ from aiohttp import web
16
+ from aiohttp.web_request import Request
17
+ from aiohttp.web_response import Response
18
+ from prometheus_client import CONTENT_TYPE_LATEST, Gauge, generate_latest
16
19
 
17
20
  from hatchet_sdk import Context
18
21
  from hatchet_sdk.client import Client, new_client_raw
@@ -88,6 +91,10 @@ class Worker:
88
91
 
89
92
  self._setup_signal_handlers()
90
93
 
94
+ self.worker_status_gauge = Gauge(
95
+ "hatchet_worker_status", "Current status of the Hatchet worker"
96
+ )
97
+
91
98
  def register_function(self, action: str, func: Callable[[Context], Any]) -> None:
92
99
  self.action_registry[action] = func
93
100
 
@@ -155,6 +162,39 @@ class Worker:
155
162
  created_loop = True
156
163
  return created_loop
157
164
 
165
+ async def health_check_handler(self, request: Request) -> Response:
166
+ status = self.status()
167
+
168
+ return web.json_response({"status": status.name})
169
+
170
+ async def metrics_handler(self, request: Request) -> Response:
171
+ self.worker_status_gauge.set(1 if self.status() == WorkerStatus.HEALTHY else 0)
172
+
173
+ return web.Response(body=generate_latest(), content_type="text/plain")
174
+
175
+ async def start_health_server(self) -> None:
176
+ port = self.config.worker_healthcheck_port or 8001
177
+
178
+ app = web.Application()
179
+ app.add_routes(
180
+ [
181
+ web.get("/health", self.health_check_handler),
182
+ web.get("/metrics", self.metrics_handler),
183
+ ]
184
+ )
185
+
186
+ runner = web.AppRunner(app)
187
+
188
+ try:
189
+ await runner.setup()
190
+ await web.TCPSite(runner, "0.0.0.0", port).start()
191
+ except Exception as e:
192
+ logger.error("failed to start healthcheck server")
193
+ logger.error(str(e))
194
+ return
195
+
196
+ logger.info(f"healthcheck server running on port {port}")
197
+
158
198
  def start(
159
199
  self, options: WorkerStartOptions = WorkerStartOptions()
160
200
  ) -> Future[asyncio.Task[Any] | None]:
@@ -196,6 +236,9 @@ class Worker:
196
236
  if not _from_start:
197
237
  self.setup_loop(options.loop)
198
238
 
239
+ if self.config.worker_healthcheck_enabled:
240
+ await self.start_health_server()
241
+
199
242
  self.action_listener_process = self._start_listener()
200
243
 
201
244
  self.action_runner = self._run_action_runner()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hatchet-sdk
3
- Version: 0.42.5
3
+ Version: 0.43.1
4
4
  Summary:
5
5
  Author: Alexander Belanger
6
6
  Author-email: alexander@hatchet.run
@@ -17,12 +17,13 @@ Requires-Dist: grpcio (>=1.68.1,<2.0.0)
17
17
  Requires-Dist: grpcio-tools (>=1.68.1,<2.0.0)
18
18
  Requires-Dist: loguru (>=0.7.2,<0.8.0)
19
19
  Requires-Dist: nest-asyncio (>=1.6.0,<2.0.0)
20
- Requires-Dist: opentelemetry-api (>=1.27.0,<2.0.0)
21
- Requires-Dist: opentelemetry-distro (>=0.48b0,<0.49)
22
- Requires-Dist: opentelemetry-exporter-otlp (>=1.27.0,<2.0.0)
23
- Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.27.0,<2.0.0)
24
- Requires-Dist: opentelemetry-instrumentation (>=0.48b0,<0.49)
25
- Requires-Dist: opentelemetry-sdk (>=1.27.0,<2.0.0)
20
+ Requires-Dist: opentelemetry-api (>=1.28.0,<2.0.0)
21
+ Requires-Dist: opentelemetry-distro (>=0.49b0)
22
+ Requires-Dist: opentelemetry-exporter-otlp (>=1.28.0,<2.0.0)
23
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.28.0,<2.0.0)
24
+ Requires-Dist: opentelemetry-instrumentation (>=0.49b0)
25
+ Requires-Dist: opentelemetry-sdk (>=1.28.0,<2.0.0)
26
+ Requires-Dist: prometheus-client (>=0.21.1,<0.22.0)
26
27
  Requires-Dist: protobuf (>=5.29.1,<6.0.0)
27
28
  Requires-Dist: pydantic (>=2.6.3,<3.0.0)
28
29
  Requires-Dist: python-dateutil (>=2.9.0.post0,<3.0.0)
@@ -203,11 +203,12 @@ hatchet_sdk/contracts/workflows_pb2.pyi,sha256=2r5d4DWaR0kwY8jKSzcffTAMMlWrusRXC
203
203
  hatchet_sdk/contracts/workflows_pb2_grpc.py,sha256=AFu0wRpfyCyNVIYZLKian6s5qPnVDCwtuE91JMaMmUI,10522
204
204
  hatchet_sdk/features/cron.py,sha256=4lKMH0MqiN8cHJk2jhF0Ueqs6z5ozwJzlOeSeaWqvO0,10217
205
205
  hatchet_sdk/features/scheduled.py,sha256=YhEbNWl8dWOH61rXVjAyu8iG1BZqpSkD4kgaxkKIHgY,9504
206
- hatchet_sdk/hatchet.py,sha256=UpCDv3q-Mrbwi7tFHS2FonBwwXlbs5kRFfCfx4DJVeI,10027
206
+ hatchet_sdk/hatchet.py,sha256=L6O9cTeZtGqFUxO5H8knXKdiej0iAequ1Wl7vSNO9FY,10027
207
207
  hatchet_sdk/labels.py,sha256=Axfp1yUNowzE9mL8AQA1ADqwOaNmq3QP_45wb1Ed1aI,272
208
- hatchet_sdk/loader.py,sha256=dGs6Tt8wdEgHeCBesbbQsP6ZYiARBvoqwIdXIO1P5Os,7913
208
+ hatchet_sdk/loader.py,sha256=ddwQ7BAWYsJ9LEsNxajCkv78hRLUMftVG0vdg5V09iQ,8746
209
209
  hatchet_sdk/logger.py,sha256=5uOr52T4mImSQm1QvWT8HvZFK5WfPNh3Y1cBQZRFgUQ,333
210
210
  hatchet_sdk/metadata.py,sha256=M_Cb-CXRKitzVMQHeaHUtbY28ET__fAbyGX1YKaeN4I,80
211
+ hatchet_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
211
212
  hatchet_sdk/rate_limit.py,sha256=IIzpe65i-518t9kQcZVEykDQ2VY8sOw2F7qlQ4wlAjw,4421
212
213
  hatchet_sdk/semver.py,sha256=PrgBL0TnyXl3p_OK1iSMk9Gpujfh5asQpJ4DHJLCW2k,998
213
214
  hatchet_sdk/token.py,sha256=Ap3jnbaPAL10F2G_D71wj7OpBcvrI3RuE0keqXx1lAE,698
@@ -226,10 +227,10 @@ hatchet_sdk/worker/runner/run_loop_manager.py,sha256=nV7fhNxJKCcrBm0ci118aszF_7A
226
227
  hatchet_sdk/worker/runner/runner.py,sha256=uNHPViiQvtwvX4uJ9TqcbFPonJnhhoEM3WNOWEKyop0,18517
227
228
  hatchet_sdk/worker/runner/utils/capture_logs.py,sha256=s_BGxeykelVbusx6u31EPx3vv9c2BHkuBnYcaLW680E,2381
228
229
  hatchet_sdk/worker/runner/utils/error_with_traceback.py,sha256=Iih_s8JNqrinXETFJ3ZS88EhaTekfM6m5fqIP7QWoIM,181
229
- hatchet_sdk/worker/worker.py,sha256=R4UEf_1e7qe1LrXS8-0fjfriwcSb3W_38RUR6pOxBCo,11547
230
+ hatchet_sdk/worker/worker.py,sha256=7UPm3qTzNYSSm9QTNX6zBBMJqVA6nKFeCbAdqLLjUBs,13007
230
231
  hatchet_sdk/workflow.py,sha256=XRj5jcCQSvPQMXxBipf-ZlARua2E8Z9igRzGcQ5alkI,9375
231
232
  hatchet_sdk/workflow_run.py,sha256=BwK5cefvXXvyQ1Ednj_7LeejMwQJqWnvUC_FTBmJNxk,1805
232
- hatchet_sdk-0.42.5.dist-info/METADATA,sha256=BztALlvM5Evu2RNQwVaMfnWJR6WqsKwgxCE3HCb4oZg,1514
233
- hatchet_sdk-0.42.5.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
234
- hatchet_sdk-0.42.5.dist-info/entry_points.txt,sha256=LTtQRABmSGYOxRI68cUVEz5dp9Qb57eqXGic9lU8RMo,1023
235
- hatchet_sdk-0.42.5.dist-info/RECORD,,
233
+ hatchet_sdk-0.43.1.dist-info/METADATA,sha256=E9nxiPbh3-x6S1TPXCVhPmgAm3sqolSmtIW8xPQ2wws,1554
234
+ hatchet_sdk-0.43.1.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
235
+ hatchet_sdk-0.43.1.dist-info/entry_points.txt,sha256=LTtQRABmSGYOxRI68cUVEz5dp9Qb57eqXGic9lU8RMo,1023
236
+ hatchet_sdk-0.43.1.dist-info/RECORD,,