hatchet-sdk 0.40.0a9__py3-none-any.whl → 0.42.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/clients/admin.py +129 -59
- hatchet_sdk/clients/dispatcher/action_listener.py +25 -2
- hatchet_sdk/clients/events.py +91 -52
- hatchet_sdk/clients/rest/__init__.py +21 -0
- hatchet_sdk/clients/rest/api/api_token_api.py +12 -9
- hatchet_sdk/clients/rest/api/default_api.py +24 -18
- hatchet_sdk/clients/rest/api/event_api.py +32 -24
- hatchet_sdk/clients/rest/api/github_api.py +4 -3
- hatchet_sdk/clients/rest/api/log_api.py +4 -3
- hatchet_sdk/clients/rest/api/metadata_api.py +12 -9
- hatchet_sdk/clients/rest/api/rate_limits_api.py +7 -4
- hatchet_sdk/clients/rest/api/slack_api.py +8 -6
- hatchet_sdk/clients/rest/api/sns_api.py +12 -9
- hatchet_sdk/clients/rest/api/step_run_api.py +28 -21
- hatchet_sdk/clients/rest/api/tenant_api.py +67 -49
- hatchet_sdk/clients/rest/api/user_api.py +24 -18
- hatchet_sdk/clients/rest/api/worker_api.py +12 -9
- hatchet_sdk/clients/rest/api/workflow_api.py +3073 -936
- hatchet_sdk/clients/rest/api/workflow_run_api.py +669 -21
- hatchet_sdk/clients/rest/api_client.py +34 -11
- hatchet_sdk/clients/rest/configuration.py +161 -36
- hatchet_sdk/clients/rest/models/__init__.py +21 -0
- hatchet_sdk/clients/rest/models/api_errors.py +3 -3
- hatchet_sdk/clients/rest/models/bulk_create_event_request.py +3 -3
- hatchet_sdk/clients/rest/models/bulk_create_event_response.py +3 -3
- hatchet_sdk/clients/{cloud_rest/models/managed_worker_create_request_build_config_steps_inner.py → rest/models/create_cron_workflow_trigger_request.py} +18 -14
- hatchet_sdk/clients/{cloud_rest/models/github_app_list_installations200_response_rows_inner.py → rest/models/cron_workflows.py} +54 -21
- hatchet_sdk/clients/{cloud_rest/models/log_list200_response.py → rest/models/cron_workflows_list.py} +13 -22
- hatchet_sdk/clients/rest/models/cron_workflows_order_by_field.py +37 -0
- hatchet_sdk/clients/rest/models/event_list.py +3 -3
- hatchet_sdk/clients/rest/models/get_step_run_diff_response.py +3 -3
- hatchet_sdk/clients/rest/models/job.py +3 -3
- hatchet_sdk/clients/rest/models/job_run.py +3 -3
- hatchet_sdk/clients/rest/models/list_api_tokens_response.py +3 -3
- hatchet_sdk/clients/rest/models/list_pull_requests_response.py +3 -3
- hatchet_sdk/clients/rest/models/list_slack_webhooks.py +3 -3
- hatchet_sdk/clients/rest/models/list_sns_integrations.py +3 -3
- hatchet_sdk/clients/rest/models/log_line_list.py +3 -3
- hatchet_sdk/clients/rest/models/rate_limit_list.py +3 -3
- hatchet_sdk/clients/rest/models/replay_workflow_runs_response.py +3 -3
- hatchet_sdk/clients/{cloud_rest/models/log_list200_response_rows_inner.py → rest/models/schedule_workflow_run_request.py} +12 -12
- hatchet_sdk/clients/rest/models/scheduled_run_status.py +42 -0
- hatchet_sdk/clients/rest/models/scheduled_workflows.py +153 -0
- hatchet_sdk/clients/{cloud_rest/models/managed_worker_list200_response.py → rest/models/scheduled_workflows_list.py} +13 -22
- hatchet_sdk/clients/rest/models/scheduled_workflows_order_by_field.py +37 -0
- hatchet_sdk/clients/rest/models/step_run_archive_list.py +3 -3
- hatchet_sdk/clients/rest/models/step_run_event_list.py +3 -3
- hatchet_sdk/clients/rest/models/tenant_alert_email_group_list.py +3 -3
- hatchet_sdk/clients/rest/models/tenant_invite_list.py +3 -3
- hatchet_sdk/clients/rest/models/tenant_list.py +3 -3
- hatchet_sdk/clients/rest/models/tenant_member_list.py +3 -3
- hatchet_sdk/clients/rest/models/tenant_queue_metrics.py +16 -0
- hatchet_sdk/clients/rest/models/tenant_resource_policy.py +3 -3
- hatchet_sdk/clients/rest/models/tenant_step_run_queue_metrics.py +1 -1
- hatchet_sdk/clients/rest/models/user_tenant_memberships_list.py +3 -3
- hatchet_sdk/clients/rest/models/webhook_worker_list_response.py +3 -3
- hatchet_sdk/clients/rest/models/webhook_worker_request_list_response.py +3 -3
- hatchet_sdk/clients/rest/models/worker.py +20 -9
- hatchet_sdk/clients/rest/models/worker_list.py +3 -3
- hatchet_sdk/clients/{cloud_rest/models/tenant_billing_state_get200_response_payment_methods_inner.py → rest/models/worker_runtime_info.py} +23 -19
- hatchet_sdk/clients/rest/models/worker_runtime_sdks.py +38 -0
- hatchet_sdk/clients/rest/models/workflow.py +9 -9
- hatchet_sdk/clients/rest/models/workflow_list.py +3 -3
- hatchet_sdk/clients/rest/models/workflow_run.py +3 -3
- hatchet_sdk/clients/rest/models/workflow_run_list.py +3 -3
- hatchet_sdk/clients/rest/models/workflow_run_shape.py +3 -3
- hatchet_sdk/clients/rest/models/workflow_runs_metrics.py +1 -5
- hatchet_sdk/clients/rest/models/workflow_triggers.py +6 -6
- hatchet_sdk/clients/rest/models/workflow_version.py +3 -3
- hatchet_sdk/clients/rest/rest.py +3 -3
- hatchet_sdk/clients/rest_client.py +200 -21
- hatchet_sdk/contracts/dispatcher_pb2.py +71 -67
- hatchet_sdk/contracts/dispatcher_pb2.pyi +31 -2
- hatchet_sdk/contracts/events_pb2.pyi +2 -0
- hatchet_sdk/contracts/workflows_pb2.py +42 -40
- hatchet_sdk/contracts/workflows_pb2.pyi +24 -6
- hatchet_sdk/features/cron.py +286 -0
- hatchet_sdk/features/scheduled.py +248 -0
- hatchet_sdk/hatchet.py +80 -79
- hatchet_sdk/loader.py +37 -14
- hatchet_sdk/utils/serialization.py +15 -0
- hatchet_sdk/utils/tracing.py +67 -0
- hatchet_sdk/worker/runner/runner.py +158 -112
- hatchet_sdk/worker/worker.py +1 -17
- hatchet_sdk/workflow.py +4 -0
- {hatchet_sdk-0.40.0a9.dist-info → hatchet_sdk-0.42.0.dist-info}/METADATA +8 -2
- {hatchet_sdk-0.40.0a9.dist-info → hatchet_sdk-0.42.0.dist-info}/RECORD +89 -143
- {hatchet_sdk-0.40.0a9.dist-info → hatchet_sdk-0.42.0.dist-info}/entry_points.txt +1 -1
- hatchet_sdk/clients/cloud_rest/__init__.py +0 -186
- hatchet_sdk/clients/cloud_rest/api/__init__.py +0 -14
- hatchet_sdk/clients/cloud_rest/api/billing_api.py +0 -819
- hatchet_sdk/clients/cloud_rest/api/build_api.py +0 -298
- hatchet_sdk/clients/cloud_rest/api/feature_flags_api.py +0 -295
- hatchet_sdk/clients/cloud_rest/api/github_api.py +0 -1347
- hatchet_sdk/clients/cloud_rest/api/log_api.py +0 -971
- hatchet_sdk/clients/cloud_rest/api/managed_worker_api.py +0 -2546
- hatchet_sdk/clients/cloud_rest/api/metadata_api.py +0 -265
- hatchet_sdk/clients/cloud_rest/api/metrics_api.py +0 -1026
- hatchet_sdk/clients/cloud_rest/api/tenant_api.py +0 -301
- hatchet_sdk/clients/cloud_rest/api/user_api.py +0 -473
- hatchet_sdk/clients/cloud_rest/api/workflow_api.py +0 -369
- hatchet_sdk/clients/cloud_rest/api_client.py +0 -727
- hatchet_sdk/clients/cloud_rest/api_response.py +0 -22
- hatchet_sdk/clients/cloud_rest/configuration.py +0 -488
- hatchet_sdk/clients/cloud_rest/exceptions.py +0 -200
- hatchet_sdk/clients/cloud_rest/models/__init__.py +0 -157
- hatchet_sdk/clients/cloud_rest/models/billing_portal_link_get200_response.py +0 -85
- hatchet_sdk/clients/cloud_rest/models/build_get200_response.py +0 -121
- hatchet_sdk/clients/cloud_rest/models/github_app_list_branches200_response_inner.py +0 -86
- hatchet_sdk/clients/cloud_rest/models/github_app_list_installations200_response.py +0 -119
- hatchet_sdk/clients/cloud_rest/models/github_app_list_installations200_response_pagination.py +0 -95
- hatchet_sdk/clients/cloud_rest/models/github_app_list_installations200_response_rows_inner_metadata.py +0 -98
- hatchet_sdk/clients/cloud_rest/models/github_app_list_repos200_response_inner.py +0 -86
- hatchet_sdk/clients/cloud_rest/models/infra_as_code_create_request.py +0 -107
- hatchet_sdk/clients/cloud_rest/models/log_create_request_inner.py +0 -136
- hatchet_sdk/clients/cloud_rest/models/log_create_request_inner_event.py +0 -83
- hatchet_sdk/clients/cloud_rest/models/log_create_request_inner_fly.py +0 -100
- hatchet_sdk/clients/cloud_rest/models/log_create_request_inner_fly_app.py +0 -86
- hatchet_sdk/clients/cloud_rest/models/log_create_request_inner_log.py +0 -83
- hatchet_sdk/clients/cloud_rest/models/managed_worker_create_request.py +0 -128
- hatchet_sdk/clients/cloud_rest/models/managed_worker_create_request_build_config.py +0 -121
- hatchet_sdk/clients/cloud_rest/models/managed_worker_create_request_runtime_config.py +0 -166
- hatchet_sdk/clients/cloud_rest/models/managed_worker_events_list200_response.py +0 -119
- hatchet_sdk/clients/cloud_rest/models/managed_worker_events_list200_response_rows_inner.py +0 -117
- hatchet_sdk/clients/cloud_rest/models/managed_worker_instances_list200_response.py +0 -119
- hatchet_sdk/clients/cloud_rest/models/managed_worker_instances_list200_response_rows_inner.py +0 -113
- hatchet_sdk/clients/cloud_rest/models/managed_worker_list200_response_rows_inner.py +0 -154
- hatchet_sdk/clients/cloud_rest/models/managed_worker_list200_response_rows_inner_build_config.py +0 -151
- hatchet_sdk/clients/cloud_rest/models/managed_worker_list200_response_rows_inner_build_config_steps_inner.py +0 -109
- hatchet_sdk/clients/cloud_rest/models/managed_worker_list200_response_rows_inner_runtime_configs_inner.py +0 -171
- hatchet_sdk/clients/cloud_rest/models/managed_worker_update_request.py +0 -131
- hatchet_sdk/clients/cloud_rest/models/metadata_get200_response.py +0 -101
- hatchet_sdk/clients/cloud_rest/models/metadata_get400_response.py +0 -105
- hatchet_sdk/clients/cloud_rest/models/metadata_get400_response_errors_inner.py +0 -102
- hatchet_sdk/clients/cloud_rest/models/metrics_cpu_get200_response_inner.py +0 -108
- hatchet_sdk/clients/cloud_rest/models/metrics_cpu_get200_response_inner_histograms_inner.py +0 -102
- hatchet_sdk/clients/cloud_rest/models/metrics_cpu_get200_response_inner_histograms_inner_histogram.py +0 -113
- hatchet_sdk/clients/cloud_rest/models/metrics_cpu_get200_response_inner_histograms_inner_histogram_buckets_inner.py +0 -93
- hatchet_sdk/clients/cloud_rest/models/runtime_config_list_actions200_response.py +0 -83
- hatchet_sdk/clients/cloud_rest/models/subscription_upsert200_response.py +0 -114
- hatchet_sdk/clients/cloud_rest/models/subscription_upsert_request.py +0 -88
- hatchet_sdk/clients/cloud_rest/models/tenant_billing_state_get200_response.py +0 -170
- hatchet_sdk/clients/cloud_rest/models/tenant_billing_state_get200_response_coupons_inner.py +0 -137
- hatchet_sdk/clients/cloud_rest/models/tenant_billing_state_get200_response_plans_inner.py +0 -103
- hatchet_sdk/clients/cloud_rest/models/tenant_billing_state_get200_response_subscription.py +0 -114
- hatchet_sdk/clients/cloud_rest/models/workflow_run_events_get_metrics200_response.py +0 -107
- hatchet_sdk/clients/cloud_rest/models/workflow_run_events_get_metrics200_response_results_inner.py +0 -105
- hatchet_sdk/clients/cloud_rest/rest.py +0 -182
- hatchet_sdk/compute/__init__.py +0 -0
- hatchet_sdk/compute/configs.py +0 -34
- hatchet_sdk/compute/managed_compute.py +0 -111
- {hatchet_sdk-0.40.0a9.dist-info → hatchet_sdk-0.42.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
from typing import Any, Coroutine, Dict, List, Optional, Union
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
|
|
6
|
+
from hatchet_sdk.client import Client
|
|
7
|
+
from hatchet_sdk.clients.rest.models.cron_workflows import CronWorkflows
|
|
8
|
+
from hatchet_sdk.clients.rest.models.cron_workflows_order_by_field import (
|
|
9
|
+
CronWorkflowsOrderByField,
|
|
10
|
+
)
|
|
11
|
+
from hatchet_sdk.clients.rest.models.scheduled_workflows import ScheduledWorkflows
|
|
12
|
+
from hatchet_sdk.clients.rest.models.scheduled_workflows_list import (
|
|
13
|
+
ScheduledWorkflowsList,
|
|
14
|
+
)
|
|
15
|
+
from hatchet_sdk.clients.rest.models.workflow_run_order_by_direction import (
|
|
16
|
+
WorkflowRunOrderByDirection,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CreateScheduledTriggerInput(BaseModel):
|
|
21
|
+
"""
|
|
22
|
+
Schema for creating a scheduled workflow run.
|
|
23
|
+
|
|
24
|
+
Attributes:
|
|
25
|
+
input (Dict[str, Any]): The input data for the scheduled workflow.
|
|
26
|
+
additional_metadata (Dict[str, str]): Additional metadata associated with the future run (e.g. ["key1:value1", "key2:value2"]).
|
|
27
|
+
trigger_at (Optional[datetime.datetime]): The datetime when the run should be triggered.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
input: Dict[str, Any] = {}
|
|
31
|
+
additional_metadata: Dict[str, str] = {}
|
|
32
|
+
trigger_at: Optional[datetime.datetime] = None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ScheduledClient:
|
|
36
|
+
"""
|
|
37
|
+
Client for managing scheduled workflows synchronously.
|
|
38
|
+
|
|
39
|
+
Attributes:
|
|
40
|
+
_client (Client): The underlying client used to interact with the REST API.
|
|
41
|
+
aio (ScheduledClientAsync): Asynchronous counterpart of ScheduledClient.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
_client: Client
|
|
45
|
+
|
|
46
|
+
def __init__(self, _client: Client) -> None:
|
|
47
|
+
"""
|
|
48
|
+
Initializes the ScheduledClient with a given Client instance.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
_client (Client): The client instance to be used for REST interactions.
|
|
52
|
+
"""
|
|
53
|
+
self._client = _client
|
|
54
|
+
self.aio: "ScheduledClientAsync" = ScheduledClientAsync(_client)
|
|
55
|
+
|
|
56
|
+
def create(
|
|
57
|
+
self,
|
|
58
|
+
workflow_name: str,
|
|
59
|
+
trigger_at: datetime.datetime,
|
|
60
|
+
input: Dict[str, Any],
|
|
61
|
+
additional_metadata: Dict[str, str],
|
|
62
|
+
) -> ScheduledWorkflows:
|
|
63
|
+
"""
|
|
64
|
+
Creates a new scheduled workflow run asynchronously.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
workflow_name (str): The name of the scheduled workflow.
|
|
68
|
+
trigger_at (datetime.datetime): The datetime when the run should be triggered.
|
|
69
|
+
input (Dict[str, Any]): The input data for the scheduled workflow.
|
|
70
|
+
additional_metadata (Dict[str, str]): Additional metadata associated with the future run as a key-value pair (e.g. {"key1": "value1", "key2": "value2"}).
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
ScheduledWorkflows: The created scheduled workflow instance.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
validated_input = CreateScheduledTriggerInput(
|
|
77
|
+
trigger_at=trigger_at, input=input, additional_metadata=additional_metadata
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
return self._client.rest.schedule_create(
|
|
81
|
+
workflow_name,
|
|
82
|
+
validated_input.trigger_at,
|
|
83
|
+
validated_input.input,
|
|
84
|
+
validated_input.additional_metadata,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
def delete(self, scheduled: Union[str, ScheduledWorkflows]) -> None:
|
|
88
|
+
"""
|
|
89
|
+
Deletes a scheduled workflow run.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
scheduled (Union[str, ScheduledWorkflows]): The scheduled workflow trigger ID or ScheduledWorkflows instance to delete.
|
|
93
|
+
"""
|
|
94
|
+
id_ = scheduled
|
|
95
|
+
if isinstance(scheduled, ScheduledWorkflows):
|
|
96
|
+
id_ = scheduled.metadata.id
|
|
97
|
+
self._client.rest.schedule_delete(id_)
|
|
98
|
+
|
|
99
|
+
def list(
|
|
100
|
+
self,
|
|
101
|
+
offset: Optional[int] = None,
|
|
102
|
+
limit: Optional[int] = None,
|
|
103
|
+
workflow_id: Optional[str] = None,
|
|
104
|
+
additional_metadata: Optional[List[str]] = None,
|
|
105
|
+
order_by_field: Optional[CronWorkflowsOrderByField] = None,
|
|
106
|
+
order_by_direction: Optional[WorkflowRunOrderByDirection] = None,
|
|
107
|
+
) -> ScheduledWorkflowsList:
|
|
108
|
+
"""
|
|
109
|
+
Retrieves a list of scheduled workflows based on provided filters.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
offset (Optional[int]): The starting point for the list.
|
|
113
|
+
limit (Optional[int]): The maximum number of items to return.
|
|
114
|
+
workflow_id (Optional[str]): Filter by specific workflow ID.
|
|
115
|
+
additional_metadata (Optional[List[str]]): Filter by additional metadata keys (e.g. ["key1:value1", "key2:value2"]).
|
|
116
|
+
order_by_field (Optional[CronWorkflowsOrderByField]): Field to order the results by.
|
|
117
|
+
order_by_direction (Optional[WorkflowRunOrderByDirection]): Direction to order the results.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
List[ScheduledWorkflows]: A list of scheduled workflows matching the criteria.
|
|
121
|
+
"""
|
|
122
|
+
return self._client.rest.schedule_list(
|
|
123
|
+
offset=offset,
|
|
124
|
+
limit=limit,
|
|
125
|
+
workflow_id=workflow_id,
|
|
126
|
+
additional_metadata=additional_metadata,
|
|
127
|
+
order_by_field=order_by_field,
|
|
128
|
+
order_by_direction=order_by_direction,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
def get(self, scheduled: Union[str, ScheduledWorkflows]) -> ScheduledWorkflows:
|
|
132
|
+
"""
|
|
133
|
+
Retrieves a specific scheduled workflow by scheduled run trigger ID.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
scheduled (Union[str, ScheduledWorkflows]): The scheduled workflow trigger ID or ScheduledWorkflows instance to retrieve.
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
ScheduledWorkflows: The requested scheduled workflow instance.
|
|
140
|
+
"""
|
|
141
|
+
id_ = scheduled
|
|
142
|
+
if isinstance(scheduled, ScheduledWorkflows):
|
|
143
|
+
id_ = scheduled.metadata.id
|
|
144
|
+
return self._client.rest.schedule_get(id_)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class ScheduledClientAsync:
|
|
148
|
+
"""
|
|
149
|
+
Asynchronous client for managing scheduled workflows.
|
|
150
|
+
|
|
151
|
+
Attributes:
|
|
152
|
+
_client (Client): The underlying client used to interact with the REST API asynchronously.
|
|
153
|
+
"""
|
|
154
|
+
|
|
155
|
+
_client: Client
|
|
156
|
+
|
|
157
|
+
def __init__(self, _client: Client) -> None:
|
|
158
|
+
"""
|
|
159
|
+
Initializes the ScheduledClientAsync with a given Client instance.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
_client (Client): The client instance to be used for asynchronous REST interactions.
|
|
163
|
+
"""
|
|
164
|
+
self._client = _client
|
|
165
|
+
|
|
166
|
+
async def create(
|
|
167
|
+
self,
|
|
168
|
+
workflow_name: str,
|
|
169
|
+
trigger_at: datetime.datetime,
|
|
170
|
+
input: Dict[str, Any],
|
|
171
|
+
additional_metadata: Dict[str, str],
|
|
172
|
+
) -> ScheduledWorkflows:
|
|
173
|
+
"""
|
|
174
|
+
Creates a new scheduled workflow run asynchronously.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
workflow_name (str): The name of the scheduled workflow.
|
|
178
|
+
trigger_at (datetime.datetime): The datetime when the run should be triggered.
|
|
179
|
+
input (Dict[str, Any]): The input data for the scheduled workflow.
|
|
180
|
+
additional_metadata (Dict[str, str]): Additional metadata associated with the future run.
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
ScheduledWorkflows: The created scheduled workflow instance.
|
|
184
|
+
"""
|
|
185
|
+
return await self._client.rest.aio.schedule_create(
|
|
186
|
+
workflow_name, trigger_at, input, additional_metadata
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
async def delete(self, scheduled: Union[str, ScheduledWorkflows]) -> None:
|
|
190
|
+
"""
|
|
191
|
+
Deletes a scheduled workflow asynchronously.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
scheduled (Union[str, ScheduledWorkflows]): The scheduled workflow trigger ID or ScheduledWorkflows instance to delete.
|
|
195
|
+
"""
|
|
196
|
+
id_ = scheduled
|
|
197
|
+
if isinstance(scheduled, ScheduledWorkflows):
|
|
198
|
+
id_ = scheduled.metadata.id
|
|
199
|
+
await self._client.rest.aio.schedule_delete(id_)
|
|
200
|
+
|
|
201
|
+
async def list(
|
|
202
|
+
self,
|
|
203
|
+
offset: Optional[int] = None,
|
|
204
|
+
limit: Optional[int] = None,
|
|
205
|
+
workflow_id: Optional[str] = None,
|
|
206
|
+
additional_metadata: Optional[List[str]] = None,
|
|
207
|
+
order_by_field: Optional[CronWorkflowsOrderByField] = None,
|
|
208
|
+
order_by_direction: Optional[WorkflowRunOrderByDirection] = None,
|
|
209
|
+
) -> ScheduledWorkflowsList:
|
|
210
|
+
"""
|
|
211
|
+
Retrieves a list of scheduled workflows based on provided filters asynchronously.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
offset (Optional[int]): The starting point for the list.
|
|
215
|
+
limit (Optional[int]): The maximum number of items to return.
|
|
216
|
+
workflow_id (Optional[str]): Filter by specific workflow ID.
|
|
217
|
+
additional_metadata (Optional[List[str]]): Filter by additional metadata keys (e.g. ["key1:value1", "key2:value2"]).
|
|
218
|
+
order_by_field (Optional[CronWorkflowsOrderByField]): Field to order the results by.
|
|
219
|
+
order_by_direction (Optional[WorkflowRunOrderByDirection]): Direction to order the results.
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
ScheduledWorkflowsList: A list of scheduled workflows matching the criteria.
|
|
223
|
+
"""
|
|
224
|
+
return await self._client.rest.aio.schedule_list(
|
|
225
|
+
offset=offset,
|
|
226
|
+
limit=limit,
|
|
227
|
+
workflow_id=workflow_id,
|
|
228
|
+
additional_metadata=additional_metadata,
|
|
229
|
+
order_by_field=order_by_field,
|
|
230
|
+
order_by_direction=order_by_direction,
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
async def get(
|
|
234
|
+
self, scheduled: Union[str, ScheduledWorkflows]
|
|
235
|
+
) -> ScheduledWorkflows:
|
|
236
|
+
"""
|
|
237
|
+
Retrieves a specific scheduled workflow by scheduled run trigger ID asynchronously.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
scheduled (Union[str, ScheduledWorkflows]): The scheduled workflow trigger ID or ScheduledWorkflows instance to retrieve.
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
ScheduledWorkflows: The requested scheduled workflow instance.
|
|
244
|
+
"""
|
|
245
|
+
id_ = scheduled
|
|
246
|
+
if isinstance(scheduled, ScheduledWorkflows):
|
|
247
|
+
id_ = scheduled.metadata.id
|
|
248
|
+
return await self._client.rest.aio.schedule_get(id_)
|
hatchet_sdk/hatchet.py
CHANGED
|
@@ -1,31 +1,43 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import logging
|
|
3
|
-
from typing import
|
|
3
|
+
from typing import Any, Callable, Optional, ParamSpec, TypeVar
|
|
4
4
|
|
|
5
5
|
from typing_extensions import deprecated
|
|
6
6
|
|
|
7
7
|
from hatchet_sdk.clients.rest_client import RestApi
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
|
|
9
|
+
## TODO: These type stubs need to be updated to mass MyPy, and then we can remove this ignore
|
|
10
|
+
## There are file-level type ignore lines in the corresponding .pyi files.
|
|
11
|
+
from hatchet_sdk.contracts.workflows_pb2 import ( # type: ignore[attr-defined]
|
|
10
12
|
ConcurrencyLimitStrategy,
|
|
11
13
|
CreateStepRateLimit,
|
|
12
14
|
DesiredWorkerLabels,
|
|
13
15
|
StickyStrategy,
|
|
14
16
|
)
|
|
17
|
+
from hatchet_sdk.features.cron import CronClient
|
|
18
|
+
from hatchet_sdk.features.scheduled import ScheduledClient
|
|
15
19
|
from hatchet_sdk.labels import DesiredWorkerLabel
|
|
16
20
|
from hatchet_sdk.loader import ClientConfig, ConfigLoader
|
|
17
21
|
from hatchet_sdk.rate_limit import RateLimit
|
|
18
22
|
|
|
19
23
|
from .client import Client, new_client, new_client_raw
|
|
24
|
+
from .clients.admin import AdminClient
|
|
25
|
+
from .clients.dispatcher.dispatcher import DispatcherClient
|
|
26
|
+
from .clients.events import EventClient
|
|
27
|
+
from .clients.run_event_listener import RunEventListenerClient
|
|
20
28
|
from .logger import logger
|
|
21
|
-
from .worker import Worker
|
|
29
|
+
from .worker.worker import Worker
|
|
22
30
|
from .workflow import ConcurrencyExpression, WorkflowMeta
|
|
23
31
|
|
|
32
|
+
P = ParamSpec("P")
|
|
33
|
+
R = TypeVar("R")
|
|
34
|
+
|
|
24
35
|
|
|
25
|
-
|
|
36
|
+
## TODO: Fix return type here to properly type hint the metaclass
|
|
37
|
+
def workflow( # type: ignore[no-untyped-def]
|
|
26
38
|
name: str = "",
|
|
27
|
-
on_events: list | None = None,
|
|
28
|
-
on_crons: list | None = None,
|
|
39
|
+
on_events: list[str] | None = None,
|
|
40
|
+
on_crons: list[str] | None = None,
|
|
29
41
|
version: str = "",
|
|
30
42
|
timeout: str = "60m",
|
|
31
43
|
schedule_timeout: str = "5m",
|
|
@@ -33,27 +45,10 @@ def workflow(
|
|
|
33
45
|
default_priority: int | None = None,
|
|
34
46
|
concurrency: ConcurrencyExpression | None = None,
|
|
35
47
|
):
|
|
36
|
-
"""
|
|
37
|
-
Decorator to mark a class as a workflow.
|
|
38
|
-
|
|
39
|
-
Args:
|
|
40
|
-
name (str, optional): The name of the workflow. Defaults to an empty string.
|
|
41
|
-
on_events (list, optional): A list of events that trigger the workflow. Defaults to None.
|
|
42
|
-
on_crons (list, optional): A list of cron expressions that trigger the workflow. Defaults to None.
|
|
43
|
-
version (str, optional): The version of the workflow. Defaults to an empty string.
|
|
44
|
-
timeout (str, optional): The timeout for the workflow. Defaults to "60m".
|
|
45
|
-
schedule_timeout (str, optional): The schedule timeout for the workflow. Defaults to "5m".
|
|
46
|
-
sticky (StickyStrategy, optional): The sticky strategy for the workflow. Defaults to None.
|
|
47
|
-
default_priority (int, optional): The default priority for the workflow. Defaults to None.
|
|
48
|
-
concurrency (ConcurrencyExpression, optional): The concurrency expression for the workflow. Defaults to None.
|
|
49
|
-
|
|
50
|
-
Returns:
|
|
51
|
-
function: The decorated class with workflow metadata.
|
|
52
|
-
"""
|
|
53
48
|
on_events = on_events or []
|
|
54
49
|
on_crons = on_crons or []
|
|
55
50
|
|
|
56
|
-
def inner(cls) -> WorkflowMeta:
|
|
51
|
+
def inner(cls: Any) -> WorkflowMeta:
|
|
57
52
|
cls.on_events = on_events
|
|
58
53
|
cls.on_crons = on_crons
|
|
59
54
|
cls.name = name or str(cls.__name__)
|
|
@@ -65,7 +60,9 @@ def workflow(
|
|
|
65
60
|
cls.concurrency_expression = concurrency
|
|
66
61
|
# Define a new class with the same name and bases as the original, but
|
|
67
62
|
# with WorkflowMeta as its metaclass
|
|
68
|
-
|
|
63
|
+
|
|
64
|
+
## TODO: Figure out how to type this metaclass correctly
|
|
65
|
+
return WorkflowMeta(cls.name, cls.__bases__, dict(cls.__dict__)) # type: ignore[no-untyped-call]
|
|
69
66
|
|
|
70
67
|
return inner
|
|
71
68
|
|
|
@@ -73,30 +70,16 @@ def workflow(
|
|
|
73
70
|
def step(
|
|
74
71
|
name: str = "",
|
|
75
72
|
timeout: str = "",
|
|
76
|
-
parents:
|
|
73
|
+
parents: list[str] | None = None,
|
|
77
74
|
retries: int = 0,
|
|
78
|
-
rate_limits:
|
|
79
|
-
desired_worker_labels: dict[str
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
Decorator to mark a function as a step in a workflow.
|
|
84
|
-
|
|
85
|
-
Args:
|
|
86
|
-
name (str, optional): The name of the step. Defaults to the function name.
|
|
87
|
-
timeout (str, optional): The timeout for the step. Defaults to an empty string.
|
|
88
|
-
parents (List[str], optional): A list of parent step names. Defaults to an empty list.
|
|
89
|
-
retries (int, optional): The number of retries for the step. Defaults to 0.
|
|
90
|
-
rate_limits (List[RateLimit], optional): A list of rate limits for the step. Defaults to None.
|
|
91
|
-
desired_worker_labels (dict[str:DesiredWorkerLabel], optional): A dictionary of desired worker labels. Defaults to an empty dictionary.
|
|
92
|
-
compute (Compute, optional): The compute configuration for the step. Hatchet Cloud only. Defaults to None.
|
|
93
|
-
|
|
94
|
-
Returns:
|
|
95
|
-
function: The decorated function with step metadata.
|
|
96
|
-
"""
|
|
75
|
+
rate_limits: list[RateLimit] | None = None,
|
|
76
|
+
desired_worker_labels: dict[str, DesiredWorkerLabel] = {},
|
|
77
|
+
backoff_factor: float | None = None,
|
|
78
|
+
backoff_max_seconds: int | None = None,
|
|
79
|
+
) -> Callable[[Callable[P, R]], Callable[P, R]]:
|
|
97
80
|
parents = parents or []
|
|
98
81
|
|
|
99
|
-
def inner(func):
|
|
82
|
+
def inner(func: Callable[P, R]) -> Callable[P, R]:
|
|
100
83
|
limits = None
|
|
101
84
|
if rate_limits:
|
|
102
85
|
limits = [
|
|
@@ -104,18 +87,20 @@ def step(
|
|
|
104
87
|
for rate_limit in rate_limits or []
|
|
105
88
|
]
|
|
106
89
|
|
|
107
|
-
|
|
108
|
-
func.
|
|
109
|
-
func.
|
|
110
|
-
func.
|
|
111
|
-
func.
|
|
112
|
-
func.
|
|
90
|
+
## TODO: Use Protocol here to help with MyPy errors
|
|
91
|
+
func._step_name = name.lower() or str(func.__name__).lower() # type: ignore[attr-defined]
|
|
92
|
+
func._step_parents = parents # type: ignore[attr-defined]
|
|
93
|
+
func._step_timeout = timeout # type: ignore[attr-defined]
|
|
94
|
+
func._step_retries = retries # type: ignore[attr-defined]
|
|
95
|
+
func._step_rate_limits = limits # type: ignore[attr-defined]
|
|
96
|
+
func._step_backoff_factor = backoff_factor # type: ignore[attr-defined]
|
|
97
|
+
func._step_backoff_max_seconds = backoff_max_seconds # type: ignore[attr-defined]
|
|
113
98
|
|
|
114
|
-
func._step_desired_worker_labels = {}
|
|
99
|
+
func._step_desired_worker_labels = {} # type: ignore[attr-defined]
|
|
115
100
|
|
|
116
101
|
for key, d in desired_worker_labels.items():
|
|
117
102
|
value = d["value"] if "value" in d else None
|
|
118
|
-
func._step_desired_worker_labels[key] = DesiredWorkerLabels(
|
|
103
|
+
func._step_desired_worker_labels[key] = DesiredWorkerLabels( # type: ignore[attr-defined]
|
|
119
104
|
strValue=str(value) if not isinstance(value, int) else None,
|
|
120
105
|
intValue=value if isinstance(value, int) else None,
|
|
121
106
|
required=d["required"] if "required" in d else None,
|
|
@@ -132,9 +117,11 @@ def on_failure_step(
|
|
|
132
117
|
name: str = "",
|
|
133
118
|
timeout: str = "",
|
|
134
119
|
retries: int = 0,
|
|
135
|
-
rate_limits:
|
|
136
|
-
|
|
137
|
-
|
|
120
|
+
rate_limits: list[RateLimit] | None = None,
|
|
121
|
+
backoff_factor: float | None = None,
|
|
122
|
+
backoff_max_seconds: int | None = None,
|
|
123
|
+
) -> Callable[[Callable[P, R]], Callable[P, R]]:
|
|
124
|
+
def inner(func: Callable[P, R]) -> Callable[P, R]:
|
|
138
125
|
limits = None
|
|
139
126
|
if rate_limits:
|
|
140
127
|
limits = [
|
|
@@ -142,10 +129,14 @@ def on_failure_step(
|
|
|
142
129
|
for rate_limit in rate_limits or []
|
|
143
130
|
]
|
|
144
131
|
|
|
145
|
-
|
|
146
|
-
func.
|
|
147
|
-
func.
|
|
148
|
-
func.
|
|
132
|
+
## TODO: Use Protocol here to help with MyPy errors
|
|
133
|
+
func._on_failure_step_name = name.lower() or str(func.__name__).lower() # type: ignore[attr-defined]
|
|
134
|
+
func._on_failure_step_timeout = timeout # type: ignore[attr-defined]
|
|
135
|
+
func._on_failure_step_retries = retries # type: ignore[attr-defined]
|
|
136
|
+
func._on_failure_step_rate_limits = limits # type: ignore[attr-defined]
|
|
137
|
+
func._on_failure_step_backoff_factor = backoff_factor # type: ignore[attr-defined]
|
|
138
|
+
func._on_failure_step_backoff_max_seconds = backoff_max_seconds # type: ignore[attr-defined]
|
|
139
|
+
|
|
149
140
|
return func
|
|
150
141
|
|
|
151
142
|
return inner
|
|
@@ -155,11 +146,12 @@ def concurrency(
|
|
|
155
146
|
name: str = "",
|
|
156
147
|
max_runs: int = 1,
|
|
157
148
|
limit_strategy: ConcurrencyLimitStrategy = ConcurrencyLimitStrategy.CANCEL_IN_PROGRESS,
|
|
158
|
-
):
|
|
159
|
-
def inner(func):
|
|
160
|
-
|
|
161
|
-
func.
|
|
162
|
-
func.
|
|
149
|
+
) -> Callable[[Callable[P, R]], Callable[P, R]]:
|
|
150
|
+
def inner(func: Callable[P, R]) -> Callable[P, R]:
|
|
151
|
+
## TODO: Use Protocol here to help with MyPy errors
|
|
152
|
+
func._concurrency_fn_name = name.lower() or str(func.__name__).lower() # type: ignore[attr-defined]
|
|
153
|
+
func._concurrency_max_runs = max_runs # type: ignore[attr-defined]
|
|
154
|
+
func._concurrency_limit_strategy = limit_strategy # type: ignore[attr-defined]
|
|
163
155
|
|
|
164
156
|
return func
|
|
165
157
|
|
|
@@ -180,8 +172,8 @@ class HatchetRest:
|
|
|
180
172
|
rest: RestApi
|
|
181
173
|
|
|
182
174
|
def __init__(self, config: ClientConfig = ClientConfig()):
|
|
183
|
-
|
|
184
|
-
self.rest = RestApi(
|
|
175
|
+
_config: ClientConfig = ConfigLoader(".").load_client_config(config)
|
|
176
|
+
self.rest = RestApi(_config.server_url, _config.token, _config.tenant_id)
|
|
185
177
|
|
|
186
178
|
|
|
187
179
|
class Hatchet:
|
|
@@ -192,6 +184,8 @@ class Hatchet:
|
|
|
192
184
|
for working with Hatchet workers, workflows, and steps.
|
|
193
185
|
|
|
194
186
|
Attributes:
|
|
187
|
+
cron (CronClient): Interface for cron trigger operations.
|
|
188
|
+
|
|
195
189
|
admin (AdminClient): Interface for administrative operations.
|
|
196
190
|
dispatcher (DispatcherClient): Interface for dispatching operations.
|
|
197
191
|
event (EventClient): Interface for event-related operations.
|
|
@@ -199,13 +193,17 @@ class Hatchet:
|
|
|
199
193
|
"""
|
|
200
194
|
|
|
201
195
|
_client: Client
|
|
196
|
+
cron: CronClient
|
|
197
|
+
scheduled: ScheduledClient
|
|
202
198
|
|
|
203
199
|
@classmethod
|
|
204
|
-
def from_environment(
|
|
200
|
+
def from_environment(
|
|
201
|
+
cls, defaults: ClientConfig = ClientConfig(), **kwargs: Any
|
|
202
|
+
) -> "Hatchet":
|
|
205
203
|
return cls(client=new_client(defaults), **kwargs)
|
|
206
204
|
|
|
207
205
|
@classmethod
|
|
208
|
-
def from_config(cls, config: ClientConfig, **kwargs):
|
|
206
|
+
def from_config(cls, config: ClientConfig, **kwargs: Any) -> "Hatchet":
|
|
209
207
|
return cls(client=new_client_raw(config), **kwargs)
|
|
210
208
|
|
|
211
209
|
def __init__(
|
|
@@ -230,6 +228,9 @@ class Hatchet:
|
|
|
230
228
|
if debug:
|
|
231
229
|
logger.setLevel(logging.DEBUG)
|
|
232
230
|
|
|
231
|
+
self.cron = CronClient(self._client)
|
|
232
|
+
self.scheduled = ScheduledClient(self._client)
|
|
233
|
+
|
|
233
234
|
@property
|
|
234
235
|
@deprecated(
|
|
235
236
|
"Direct access to client is deprecated and will be removed in a future version. Use specific client properties (Hatchet.admin, Hatchet.dispatcher, Hatchet.event, Hatchet.rest) instead. [0.32.0]",
|
|
@@ -238,31 +239,31 @@ class Hatchet:
|
|
|
238
239
|
return self._client
|
|
239
240
|
|
|
240
241
|
@property
|
|
241
|
-
def admin(self):
|
|
242
|
+
def admin(self) -> AdminClient:
|
|
242
243
|
return self._client.admin
|
|
243
244
|
|
|
244
245
|
@property
|
|
245
|
-
def dispatcher(self):
|
|
246
|
+
def dispatcher(self) -> DispatcherClient:
|
|
246
247
|
return self._client.dispatcher
|
|
247
248
|
|
|
248
249
|
@property
|
|
249
|
-
def event(self):
|
|
250
|
+
def event(self) -> EventClient:
|
|
250
251
|
return self._client.event
|
|
251
252
|
|
|
252
253
|
@property
|
|
253
|
-
def rest(self):
|
|
254
|
+
def rest(self) -> RestApi:
|
|
254
255
|
return self._client.rest
|
|
255
256
|
|
|
256
257
|
@property
|
|
257
|
-
def listener(self):
|
|
258
|
+
def listener(self) -> RunEventListenerClient:
|
|
258
259
|
return self._client.listener
|
|
259
260
|
|
|
260
261
|
@property
|
|
261
|
-
def config(self):
|
|
262
|
+
def config(self) -> ClientConfig:
|
|
262
263
|
return self._client.config
|
|
263
264
|
|
|
264
265
|
@property
|
|
265
|
-
def tenant_id(self):
|
|
266
|
+
def tenant_id(self) -> str:
|
|
266
267
|
return self._client.config.tenant_id
|
|
267
268
|
|
|
268
269
|
concurrency = staticmethod(concurrency)
|
|
@@ -275,7 +276,7 @@ class Hatchet:
|
|
|
275
276
|
|
|
276
277
|
def worker(
|
|
277
278
|
self, name: str, max_runs: int | None = None, labels: dict[str, str | int] = {}
|
|
278
|
-
):
|
|
279
|
+
) -> Worker:
|
|
279
280
|
try:
|
|
280
281
|
loop = asyncio.get_running_loop()
|
|
281
282
|
except RuntimeError:
|
hatchet_sdk/loader.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import os
|
|
2
3
|
from logging import Logger, getLogger
|
|
3
4
|
from typing import Dict, Optional
|
|
@@ -38,9 +39,10 @@ class ClientConfig:
|
|
|
38
39
|
logger: Logger = None,
|
|
39
40
|
grpc_max_recv_message_length: int = 4 * 1024 * 1024, # 4MB
|
|
40
41
|
grpc_max_send_message_length: int = 4 * 1024 * 1024, # 4MB
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
otel_exporter_oltp_endpoint: str | None = None,
|
|
43
|
+
otel_service_name: str | None = None,
|
|
44
|
+
otel_exporter_oltp_headers: dict[str, str] | None = None,
|
|
45
|
+
otel_exporter_oltp_protocol: str | None = None,
|
|
44
46
|
):
|
|
45
47
|
self.tenant_id = tenant_id
|
|
46
48
|
self.tls_config = tls_config
|
|
@@ -51,6 +53,10 @@ class ClientConfig:
|
|
|
51
53
|
self.logInterceptor = logger
|
|
52
54
|
self.grpc_max_recv_message_length = grpc_max_recv_message_length
|
|
53
55
|
self.grpc_max_send_message_length = grpc_max_send_message_length
|
|
56
|
+
self.otel_exporter_oltp_endpoint = otel_exporter_oltp_endpoint
|
|
57
|
+
self.otel_service_name = otel_service_name
|
|
58
|
+
self.otel_exporter_oltp_headers = otel_exporter_oltp_headers
|
|
59
|
+
self.otel_exporter_oltp_protocol = otel_exporter_oltp_protocol
|
|
54
60
|
|
|
55
61
|
if not self.logInterceptor:
|
|
56
62
|
self.logInterceptor = getLogger()
|
|
@@ -65,12 +71,6 @@ class ClientConfig:
|
|
|
65
71
|
|
|
66
72
|
self.listener_v2_timeout = listener_v2_timeout
|
|
67
73
|
|
|
68
|
-
self.runnable_actions: list[str] | None = (
|
|
69
|
-
[self.namespace + action for action in runnable_actions]
|
|
70
|
-
if runnable_actions
|
|
71
|
-
else None
|
|
72
|
-
)
|
|
73
|
-
|
|
74
74
|
|
|
75
75
|
class ConfigLoader:
|
|
76
76
|
def __init__(self, directory: str):
|
|
@@ -136,11 +136,31 @@ class ConfigLoader:
|
|
|
136
136
|
|
|
137
137
|
tls_config = self._load_tls_config(config_data["tls"], host_port)
|
|
138
138
|
|
|
139
|
-
|
|
140
|
-
"
|
|
139
|
+
otel_exporter_oltp_endpoint = get_config_value(
|
|
140
|
+
"otel_exporter_oltp_endpoint", "HATCHET_CLIENT_OTEL_EXPORTER_OTLP_ENDPOINT"
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
otel_service_name = get_config_value(
|
|
144
|
+
"otel_service_name", "HATCHET_CLIENT_OTEL_SERVICE_NAME"
|
|
141
145
|
)
|
|
142
|
-
|
|
143
|
-
|
|
146
|
+
|
|
147
|
+
_oltp_headers = get_config_value(
|
|
148
|
+
"otel_exporter_oltp_headers", "HATCHET_CLIENT_OTEL_EXPORTER_OTLP_HEADERS"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
if _oltp_headers:
|
|
152
|
+
try:
|
|
153
|
+
otel_header_key, api_key = _oltp_headers.split("=", maxsplit=1)
|
|
154
|
+
otel_exporter_oltp_headers = {otel_header_key: api_key}
|
|
155
|
+
except ValueError:
|
|
156
|
+
raise ValueError(
|
|
157
|
+
"HATCHET_CLIENT_OTEL_EXPORTER_OTLP_HEADERS must be in the format `key=value`"
|
|
158
|
+
)
|
|
159
|
+
else:
|
|
160
|
+
otel_exporter_oltp_headers = None
|
|
161
|
+
|
|
162
|
+
otel_exporter_oltp_protocol = get_config_value(
|
|
163
|
+
"otel_exporter_oltp_protocol", "HATCHET_CLIENT_OTEL_EXPORTER_OTLP_PROTOCOL"
|
|
144
164
|
)
|
|
145
165
|
|
|
146
166
|
return ClientConfig(
|
|
@@ -154,7 +174,10 @@ class ConfigLoader:
|
|
|
154
174
|
logger=defaults.logInterceptor,
|
|
155
175
|
grpc_max_recv_message_length=grpc_max_recv_message_length,
|
|
156
176
|
grpc_max_send_message_length=grpc_max_send_message_length,
|
|
157
|
-
|
|
177
|
+
otel_exporter_oltp_endpoint=otel_exporter_oltp_endpoint,
|
|
178
|
+
otel_service_name=otel_service_name,
|
|
179
|
+
otel_exporter_oltp_headers=otel_exporter_oltp_headers,
|
|
180
|
+
otel_exporter_oltp_protocol=otel_exporter_oltp_protocol,
|
|
158
181
|
)
|
|
159
182
|
|
|
160
183
|
def _load_tls_config(self, tls_data: Dict, host_port) -> ClientTLSConfig:
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def flatten(xs: dict[str, Any], parent_key: str, separator: str) -> dict[str, Any]:
|
|
5
|
+
items = []
|
|
6
|
+
|
|
7
|
+
for k, v in xs.items():
|
|
8
|
+
new_key = parent_key + separator + k if parent_key else k
|
|
9
|
+
|
|
10
|
+
if isinstance(v, dict):
|
|
11
|
+
items.extend(flatten(v, new_key, separator).items())
|
|
12
|
+
else:
|
|
13
|
+
items.append((new_key, v))
|
|
14
|
+
|
|
15
|
+
return dict(items)
|