Feat: Scheduled run detail view, bulk cancel / replay with pagination helper (#2416)

* feat: endpoint for listing external ids

* feat: wire up external id list

* chore: regen api

* feat: py sdk wrapper

* fix: since type

* fix: log

* fix: improve defaults for statuses

* feat: docs

* feat: docs

* fix: rm extra file

* feat: add id column to scheduled runs

* feat: side panel for scheduled runs

* fix: side panel header pinned

* fix: border + padding

* chore: gen

* chore: lint

* chore: changelog, version

* fix: spacing of cols

* fix: empty webhook resource limit

* fix: tsc

* fix: sort organizations and tenants alphabetically
This commit is contained in:
matt
2025-10-15 11:36:45 -04:00
committed by GitHub
parent 14894f892b
commit 5b5adcb8ed
48 changed files with 3678 additions and 520 deletions

View File

@@ -5,6 +5,12 @@ All notable changes to Hatchet's Python SDK will be documented in this changelog
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.20.1] - 2025-10-14
### Added
- Adds wrapper methods for bulk cancelling / replaying large numbers of runs with pagination.
## [1.20.0] - 2025-10-3
### Removed

View File

@@ -24,3 +24,8 @@
- get_run_ref
- get_task_run
- aio_get_task_run
- bulk_cancel_by_filters_with_pagination
- bulk_replay_by_filters_with_pagination
- aio_bulk_cancel_by_filters_with_pagination
- aio_bulk_replay_by_filters_with_pagination
- subscribe_to_stream

View File

@@ -150,6 +150,7 @@ from hatchet_sdk.clients.rest.models.rate_limit_order_by_field import (
RateLimitOrderByField,
)
from hatchet_sdk.clients.rest.models.recent_step_runs import RecentStepRuns
from hatchet_sdk.clients.rest.models.registered_workflow import RegisteredWorkflow
from hatchet_sdk.clients.rest.models.reject_invite_request import RejectInviteRequest
from hatchet_sdk.clients.rest.models.replay_event_request import ReplayEventRequest
from hatchet_sdk.clients.rest.models.replay_workflow_runs_request import (
@@ -196,6 +197,7 @@ from hatchet_sdk.clients.rest.models.tenant_alert_email_group_list import (
from hatchet_sdk.clients.rest.models.tenant_alerting_settings import (
TenantAlertingSettings,
)
from hatchet_sdk.clients.rest.models.tenant_environment import TenantEnvironment
from hatchet_sdk.clients.rest.models.tenant_invite import TenantInvite
from hatchet_sdk.clients.rest.models.tenant_invite_list import TenantInviteList
from hatchet_sdk.clients.rest.models.tenant_list import TenantList
@@ -214,12 +216,18 @@ from hatchet_sdk.clients.rest.models.tenant_version import TenantVersion
from hatchet_sdk.clients.rest.models.trigger_workflow_run_request import (
TriggerWorkflowRunRequest,
)
from hatchet_sdk.clients.rest.models.update_cron_workflow_trigger_request import (
UpdateCronWorkflowTriggerRequest,
)
from hatchet_sdk.clients.rest.models.update_tenant_alert_email_group_request import (
UpdateTenantAlertEmailGroupRequest,
)
from hatchet_sdk.clients.rest.models.update_tenant_invite_request import (
UpdateTenantInviteRequest,
)
from hatchet_sdk.clients.rest.models.update_tenant_member_request import (
UpdateTenantMemberRequest,
)
from hatchet_sdk.clients.rest.models.update_tenant_request import UpdateTenantRequest
from hatchet_sdk.clients.rest.models.update_worker_request import UpdateWorkerRequest
from hatchet_sdk.clients.rest.models.user import User
@@ -290,6 +298,9 @@ from hatchet_sdk.clients.rest.models.v1_trigger_workflow_run_request import (
from hatchet_sdk.clients.rest.models.v1_update_filter_request import (
V1UpdateFilterRequest,
)
from hatchet_sdk.clients.rest.models.v1_update_webhook_request import (
V1UpdateWebhookRequest,
)
from hatchet_sdk.clients.rest.models.v1_webhook import V1Webhook
from hatchet_sdk.clients.rest.models.v1_webhook_api_key_auth import V1WebhookAPIKeyAuth
from hatchet_sdk.clients.rest.models.v1_webhook_auth_type import V1WebhookAuthType
@@ -302,9 +313,6 @@ from hatchet_sdk.clients.rest.models.v1_webhook_hmac_encoding import (
V1WebhookHMACEncoding,
)
from hatchet_sdk.clients.rest.models.v1_webhook_list import V1WebhookList
from hatchet_sdk.clients.rest.models.v1_webhook_receive200_response import (
V1WebhookReceive200Response,
)
from hatchet_sdk.clients.rest.models.v1_webhook_source_name import V1WebhookSourceName
from hatchet_sdk.clients.rest.models.v1_workflow_run import V1WorkflowRun
from hatchet_sdk.clients.rest.models.v1_workflow_run_details import V1WorkflowRunDetails

View File

@@ -1597,6 +1597,10 @@ class TaskApi:
Optional[Annotated[str, Field(min_length=36, strict=True, max_length=36)]],
Field(description="The id of the event that triggered the task"),
] = None,
additional_metadata: Annotated[
Optional[List[StrictStr]],
Field(description="Additional metadata k-v pairs to filter by"),
] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -1625,6 +1629,8 @@ class TaskApi:
:type parent_task_external_id: str
:param triggering_event_external_id: The id of the event that triggered the task
:type triggering_event_external_id: str
:param additional_metadata: Additional metadata k-v pairs to filter by
:type additional_metadata: List[str]
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
@@ -1654,6 +1660,7 @@ class TaskApi:
workflow_ids=workflow_ids,
parent_task_external_id=parent_task_external_id,
triggering_event_external_id=triggering_event_external_id,
additional_metadata=additional_metadata,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
@@ -1704,6 +1711,10 @@ class TaskApi:
Optional[Annotated[str, Field(min_length=36, strict=True, max_length=36)]],
Field(description="The id of the event that triggered the task"),
] = None,
additional_metadata: Annotated[
Optional[List[StrictStr]],
Field(description="Additional metadata k-v pairs to filter by"),
] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -1732,6 +1743,8 @@ class TaskApi:
:type parent_task_external_id: str
:param triggering_event_external_id: The id of the event that triggered the task
:type triggering_event_external_id: str
:param additional_metadata: Additional metadata k-v pairs to filter by
:type additional_metadata: List[str]
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
@@ -1761,6 +1774,7 @@ class TaskApi:
workflow_ids=workflow_ids,
parent_task_external_id=parent_task_external_id,
triggering_event_external_id=triggering_event_external_id,
additional_metadata=additional_metadata,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
@@ -1811,6 +1825,10 @@ class TaskApi:
Optional[Annotated[str, Field(min_length=36, strict=True, max_length=36)]],
Field(description="The id of the event that triggered the task"),
] = None,
additional_metadata: Annotated[
Optional[List[StrictStr]],
Field(description="Additional metadata k-v pairs to filter by"),
] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -1839,6 +1857,8 @@ class TaskApi:
:type parent_task_external_id: str
:param triggering_event_external_id: The id of the event that triggered the task
:type triggering_event_external_id: str
:param additional_metadata: Additional metadata k-v pairs to filter by
:type additional_metadata: List[str]
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
@@ -1868,6 +1888,7 @@ class TaskApi:
workflow_ids=workflow_ids,
parent_task_external_id=parent_task_external_id,
triggering_event_external_id=triggering_event_external_id,
additional_metadata=additional_metadata,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
@@ -1893,6 +1914,7 @@ class TaskApi:
workflow_ids,
parent_task_external_id,
triggering_event_external_id,
additional_metadata,
_request_auth,
_content_type,
_headers,
@@ -1903,6 +1925,7 @@ class TaskApi:
_collection_formats: Dict[str, str] = {
"workflow_ids": "multi",
"additional_metadata": "multi",
}
_path_params: Dict[str, str] = {}
@@ -1954,6 +1977,10 @@ class TaskApi:
("triggering_event_external_id", triggering_event_external_id)
)
if additional_metadata is not None:
_query_params.append(("additional_metadata", additional_metadata))
# process the header parameters
# process the form parameters
# process the body parameter

View File

@@ -49,6 +49,9 @@ from hatchet_sdk.clients.rest.models.tenant_step_run_queue_metrics import (
from hatchet_sdk.clients.rest.models.update_tenant_alert_email_group_request import (
UpdateTenantAlertEmailGroupRequest,
)
from hatchet_sdk.clients.rest.models.update_tenant_member_request import (
UpdateTenantMemberRequest,
)
from hatchet_sdk.clients.rest.models.update_tenant_request import UpdateTenantRequest
from hatchet_sdk.clients.rest.rest import RESTResponseType
@@ -2862,6 +2865,7 @@ class TenantApi:
"201": "TenantInvite",
"400": "APIErrors",
"403": "APIError",
"422": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
@@ -2939,6 +2943,7 @@ class TenantApi:
"201": "TenantInvite",
"400": "APIErrors",
"403": "APIError",
"422": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
@@ -3016,6 +3021,7 @@ class TenantApi:
"201": "TenantInvite",
"400": "APIErrors",
"403": "APIError",
"422": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
@@ -4178,6 +4184,345 @@ class TenantApi:
_request_auth=_request_auth,
)
@validate_call
def tenant_member_update(
self,
tenant: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The tenant id"
),
],
member: Annotated[
str,
Field(
min_length=36,
strict=True,
max_length=36,
description="The tenant member id",
),
],
update_tenant_member_request: Annotated[
UpdateTenantMemberRequest,
Field(description="The tenant member properties to update"),
],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]
],
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> TenantMember:
"""Update a tenant member
Update a tenant member
:param tenant: The tenant id (required)
:type tenant: str
:param member: The tenant member id (required)
:type member: str
:param update_tenant_member_request: The tenant member properties to update (required)
:type update_tenant_member_request: UpdateTenantMemberRequest
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._tenant_member_update_serialize(
tenant=tenant,
member=member,
update_tenant_member_request=update_tenant_member_request,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index,
)
_response_types_map: Dict[str, Optional[str]] = {
"200": "TenantMember",
"400": "APIErrors",
"403": "APIErrors",
"404": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
)
response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
).data
@validate_call
def tenant_member_update_with_http_info(
self,
tenant: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The tenant id"
),
],
member: Annotated[
str,
Field(
min_length=36,
strict=True,
max_length=36,
description="The tenant member id",
),
],
update_tenant_member_request: Annotated[
UpdateTenantMemberRequest,
Field(description="The tenant member properties to update"),
],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]
],
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> ApiResponse[TenantMember]:
"""Update a tenant member
Update a tenant member
:param tenant: The tenant id (required)
:type tenant: str
:param member: The tenant member id (required)
:type member: str
:param update_tenant_member_request: The tenant member properties to update (required)
:type update_tenant_member_request: UpdateTenantMemberRequest
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._tenant_member_update_serialize(
tenant=tenant,
member=member,
update_tenant_member_request=update_tenant_member_request,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index,
)
_response_types_map: Dict[str, Optional[str]] = {
"200": "TenantMember",
"400": "APIErrors",
"403": "APIErrors",
"404": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
)
response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
)
@validate_call
def tenant_member_update_without_preload_content(
self,
tenant: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The tenant id"
),
],
member: Annotated[
str,
Field(
min_length=36,
strict=True,
max_length=36,
description="The tenant member id",
),
],
update_tenant_member_request: Annotated[
UpdateTenantMemberRequest,
Field(description="The tenant member properties to update"),
],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]
],
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> RESTResponseType:
"""Update a tenant member
Update a tenant member
:param tenant: The tenant id (required)
:type tenant: str
:param member: The tenant member id (required)
:type member: str
:param update_tenant_member_request: The tenant member properties to update (required)
:type update_tenant_member_request: UpdateTenantMemberRequest
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._tenant_member_update_serialize(
tenant=tenant,
member=member,
update_tenant_member_request=update_tenant_member_request,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index,
)
_response_types_map: Dict[str, Optional[str]] = {
"200": "TenantMember",
"400": "APIErrors",
"403": "APIErrors",
"404": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
)
return response_data.response
def _tenant_member_update_serialize(
self,
tenant,
member,
update_tenant_member_request,
_request_auth,
_content_type,
_headers,
_host_index,
) -> RequestSerialized:
_host = None
_collection_formats: Dict[str, str] = {}
_path_params: Dict[str, str] = {}
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
if tenant is not None:
_path_params["tenant"] = tenant
if member is not None:
_path_params["member"] = member
# process the query parameters
# process the header parameters
# process the form parameters
# process the body parameter
if update_tenant_member_request is not None:
_body_params = update_tenant_member_request
# set the HTTP header `Accept`
if "Accept" not in _header_params:
_header_params["Accept"] = self.api_client.select_header_accept(
["application/json"]
)
# set the HTTP header `Content-Type`
if _content_type:
_header_params["Content-Type"] = _content_type
else:
_default_content_type = self.api_client.select_header_content_type(
["application/json"]
)
if _default_content_type is not None:
_header_params["Content-Type"] = _default_content_type
# authentication setting
_auth_settings: List[str] = ["cookieAuth", "bearerAuth"]
return self.api_client.param_serialize(
method="PATCH",
resource_path="/api/v1/tenants/{tenant}/members/{member}",
path_params=_path_params,
query_params=_query_params,
header_params=_header_params,
body=_body_params,
post_params=_form_params,
files=_files,
auth_settings=_auth_settings,
collection_formats=_collection_formats,
_host=_host,
_request_auth=_request_auth,
)
@validate_call
def tenant_resource_policy_get(
self,

View File

@@ -333,6 +333,7 @@ class UserApi:
"400": "APIErrors",
"401": "APIErrors",
"405": "APIErrors",
"422": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
@@ -400,6 +401,7 @@ class UserApi:
"400": "APIErrors",
"401": "APIErrors",
"405": "APIErrors",
"422": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
@@ -467,6 +469,7 @@ class UserApi:
"400": "APIErrors",
"401": "APIErrors",
"405": "APIErrors",
"422": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
@@ -1714,6 +1717,7 @@ class UserApi:
"400": "APIErrors",
"401": "APIErrors",
"405": "APIErrors",
"422": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
@@ -1781,6 +1785,7 @@ class UserApi:
"400": "APIErrors",
"401": "APIErrors",
"405": "APIErrors",
"422": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
@@ -1848,6 +1853,7 @@ class UserApi:
"400": "APIErrors",
"401": "APIErrors",
"405": "APIErrors",
"422": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
@@ -2211,6 +2217,7 @@ class UserApi:
"400": "APIErrors",
"401": "APIErrors",
"405": "APIErrors",
"422": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
@@ -2278,6 +2285,7 @@ class UserApi:
"400": "APIErrors",
"401": "APIErrors",
"405": "APIErrors",
"422": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
@@ -2345,6 +2353,7 @@ class UserApi:
"400": "APIErrors",
"401": "APIErrors",
"405": "APIErrors",
"422": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout

View File

@@ -22,11 +22,11 @@ from hatchet_sdk.clients.rest.api_response import ApiResponse
from hatchet_sdk.clients.rest.models.v1_create_webhook_request import (
V1CreateWebhookRequest,
)
from hatchet_sdk.clients.rest.models.v1_update_webhook_request import (
V1UpdateWebhookRequest,
)
from hatchet_sdk.clients.rest.models.v1_webhook import V1Webhook
from hatchet_sdk.clients.rest.models.v1_webhook_list import V1WebhookList
from hatchet_sdk.clients.rest.models.v1_webhook_receive200_response import (
V1WebhookReceive200Response,
)
from hatchet_sdk.clients.rest.models.v1_webhook_source_name import V1WebhookSourceName
from hatchet_sdk.clients.rest.rest import RESTResponseType
@@ -1293,7 +1293,7 @@ class WebhookApi:
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> V1WebhookReceive200Response:
) -> Dict[str, object]:
"""Post a webhook message
Post an incoming webhook message
@@ -1334,7 +1334,7 @@ class WebhookApi:
)
_response_types_map: Dict[str, Optional[str]] = {
"200": "V1WebhookReceive200Response",
"200": "Dict[str, object]",
"400": "APIErrors",
"403": "APIErrors",
}
@@ -1368,7 +1368,7 @@ class WebhookApi:
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> ApiResponse[V1WebhookReceive200Response]:
) -> ApiResponse[Dict[str, object]]:
"""Post a webhook message
Post an incoming webhook message
@@ -1409,7 +1409,7 @@ class WebhookApi:
)
_response_types_map: Dict[str, Optional[str]] = {
"200": "V1WebhookReceive200Response",
"200": "Dict[str, object]",
"400": "APIErrors",
"403": "APIErrors",
}
@@ -1484,7 +1484,7 @@ class WebhookApi:
)
_response_types_map: Dict[str, Optional[str]] = {
"200": "V1WebhookReceive200Response",
"200": "Dict[str, object]",
"400": "APIErrors",
"403": "APIErrors",
}
@@ -1549,3 +1549,318 @@ class WebhookApi:
_host=_host,
_request_auth=_request_auth,
)
@validate_call
def v1_webhook_update(
self,
tenant: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The tenant id"
),
],
v1_webhook: Annotated[StrictStr, Field(description="The webhook name")],
v1_update_webhook_request: Annotated[
V1UpdateWebhookRequest,
Field(description="The input to the webhook creation"),
],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]
],
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> V1Webhook:
"""Update a webhook
Update a webhook
:param tenant: The tenant id (required)
:type tenant: str
:param v1_webhook: The webhook name (required)
:type v1_webhook: str
:param v1_update_webhook_request: The input to the webhook creation (required)
:type v1_update_webhook_request: V1UpdateWebhookRequest
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._v1_webhook_update_serialize(
tenant=tenant,
v1_webhook=v1_webhook,
v1_update_webhook_request=v1_update_webhook_request,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index,
)
_response_types_map: Dict[str, Optional[str]] = {
"200": "V1Webhook",
"400": "APIErrors",
"403": "APIErrors",
"404": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
)
response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
).data
@validate_call
def v1_webhook_update_with_http_info(
self,
tenant: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The tenant id"
),
],
v1_webhook: Annotated[StrictStr, Field(description="The webhook name")],
v1_update_webhook_request: Annotated[
V1UpdateWebhookRequest,
Field(description="The input to the webhook creation"),
],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]
],
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> ApiResponse[V1Webhook]:
"""Update a webhook
Update a webhook
:param tenant: The tenant id (required)
:type tenant: str
:param v1_webhook: The webhook name (required)
:type v1_webhook: str
:param v1_update_webhook_request: The input to the webhook creation (required)
:type v1_update_webhook_request: V1UpdateWebhookRequest
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._v1_webhook_update_serialize(
tenant=tenant,
v1_webhook=v1_webhook,
v1_update_webhook_request=v1_update_webhook_request,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index,
)
_response_types_map: Dict[str, Optional[str]] = {
"200": "V1Webhook",
"400": "APIErrors",
"403": "APIErrors",
"404": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
)
response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
)
@validate_call
def v1_webhook_update_without_preload_content(
self,
tenant: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The tenant id"
),
],
v1_webhook: Annotated[StrictStr, Field(description="The webhook name")],
v1_update_webhook_request: Annotated[
V1UpdateWebhookRequest,
Field(description="The input to the webhook creation"),
],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]
],
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> RESTResponseType:
"""Update a webhook
Update a webhook
:param tenant: The tenant id (required)
:type tenant: str
:param v1_webhook: The webhook name (required)
:type v1_webhook: str
:param v1_update_webhook_request: The input to the webhook creation (required)
:type v1_update_webhook_request: V1UpdateWebhookRequest
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._v1_webhook_update_serialize(
tenant=tenant,
v1_webhook=v1_webhook,
v1_update_webhook_request=v1_update_webhook_request,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index,
)
_response_types_map: Dict[str, Optional[str]] = {
"200": "V1Webhook",
"400": "APIErrors",
"403": "APIErrors",
"404": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
)
return response_data.response
def _v1_webhook_update_serialize(
self,
tenant,
v1_webhook,
v1_update_webhook_request,
_request_auth,
_content_type,
_headers,
_host_index,
) -> RequestSerialized:
_host = None
_collection_formats: Dict[str, str] = {}
_path_params: Dict[str, str] = {}
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
if tenant is not None:
_path_params["tenant"] = tenant
if v1_webhook is not None:
_path_params["v1-webhook"] = v1_webhook
# process the query parameters
# process the header parameters
# process the form parameters
# process the body parameter
if v1_update_webhook_request is not None:
_body_params = v1_update_webhook_request
# set the HTTP header `Accept`
if "Accept" not in _header_params:
_header_params["Accept"] = self.api_client.select_header_accept(
["application/json"]
)
# set the HTTP header `Content-Type`
if _content_type:
_header_params["Content-Type"] = _content_type
else:
_default_content_type = self.api_client.select_header_content_type(
["application/json"]
)
if _default_content_type is not None:
_header_params["Content-Type"] = _default_content_type
# authentication setting
_auth_settings: List[str] = ["cookieAuth", "bearerAuth"]
return self.api_client.param_serialize(
method="PATCH",
resource_path="/api/v1/stable/tenants/{tenant}/webhooks/{v1-webhook}",
path_params=_path_params,
query_params=_query_params,
header_params=_header_params,
body=_body_params,
post_params=_form_params,
files=_files,
auth_settings=_auth_settings,
collection_formats=_collection_formats,
_host=_host,
_request_auth=_request_auth,
)

View File

@@ -34,6 +34,9 @@ from hatchet_sdk.clients.rest.models.scheduled_workflows_order_by_field import (
ScheduledWorkflowsOrderByField,
)
from hatchet_sdk.clients.rest.models.tenant_queue_metrics import TenantQueueMetrics
from hatchet_sdk.clients.rest.models.update_cron_workflow_trigger_request import (
UpdateCronWorkflowTriggerRequest,
)
from hatchet_sdk.clients.rest.models.workflow import Workflow
from hatchet_sdk.clients.rest.models.workflow_kind import WorkflowKind
from hatchet_sdk.clients.rest.models.workflow_list import WorkflowList
@@ -1437,6 +1440,330 @@ class WorkflowApi:
_request_auth=_request_auth,
)
@validate_call
def workflow_cron_update(
self,
tenant: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The tenant id"
),
],
cron_workflow: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The cron job id"
),
],
update_cron_workflow_trigger_request: Annotated[
UpdateCronWorkflowTriggerRequest, Field(description="The input for updates")
],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]
],
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> None:
"""Update cron job workflow run
Update a cron workflow for a tenant
:param tenant: The tenant id (required)
:type tenant: str
:param cron_workflow: The cron job id (required)
:type cron_workflow: str
:param update_cron_workflow_trigger_request: The input for updates (required)
:type update_cron_workflow_trigger_request: UpdateCronWorkflowTriggerRequest
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._workflow_cron_update_serialize(
tenant=tenant,
cron_workflow=cron_workflow,
update_cron_workflow_trigger_request=update_cron_workflow_trigger_request,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index,
)
_response_types_map: Dict[str, Optional[str]] = {
"204": None,
"400": "APIErrors",
"403": "APIError",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
)
response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
).data
@validate_call
def workflow_cron_update_with_http_info(
self,
tenant: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The tenant id"
),
],
cron_workflow: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The cron job id"
),
],
update_cron_workflow_trigger_request: Annotated[
UpdateCronWorkflowTriggerRequest, Field(description="The input for updates")
],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]
],
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> ApiResponse[None]:
"""Update cron job workflow run
Update a cron workflow for a tenant
:param tenant: The tenant id (required)
:type tenant: str
:param cron_workflow: The cron job id (required)
:type cron_workflow: str
:param update_cron_workflow_trigger_request: The input for updates (required)
:type update_cron_workflow_trigger_request: UpdateCronWorkflowTriggerRequest
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._workflow_cron_update_serialize(
tenant=tenant,
cron_workflow=cron_workflow,
update_cron_workflow_trigger_request=update_cron_workflow_trigger_request,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index,
)
_response_types_map: Dict[str, Optional[str]] = {
"204": None,
"400": "APIErrors",
"403": "APIError",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
)
response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
)
@validate_call
def workflow_cron_update_without_preload_content(
self,
tenant: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The tenant id"
),
],
cron_workflow: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The cron job id"
),
],
update_cron_workflow_trigger_request: Annotated[
UpdateCronWorkflowTriggerRequest, Field(description="The input for updates")
],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]
],
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> RESTResponseType:
"""Update cron job workflow run
Update a cron workflow for a tenant
:param tenant: The tenant id (required)
:type tenant: str
:param cron_workflow: The cron job id (required)
:type cron_workflow: str
:param update_cron_workflow_trigger_request: The input for updates (required)
:type update_cron_workflow_trigger_request: UpdateCronWorkflowTriggerRequest
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._workflow_cron_update_serialize(
tenant=tenant,
cron_workflow=cron_workflow,
update_cron_workflow_trigger_request=update_cron_workflow_trigger_request,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index,
)
_response_types_map: Dict[str, Optional[str]] = {
"204": None,
"400": "APIErrors",
"403": "APIError",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
)
return response_data.response
def _workflow_cron_update_serialize(
self,
tenant,
cron_workflow,
update_cron_workflow_trigger_request,
_request_auth,
_content_type,
_headers,
_host_index,
) -> RequestSerialized:
_host = None
_collection_formats: Dict[str, str] = {}
_path_params: Dict[str, str] = {}
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
if tenant is not None:
_path_params["tenant"] = tenant
if cron_workflow is not None:
_path_params["cron-workflow"] = cron_workflow
# process the query parameters
# process the header parameters
# process the form parameters
# process the body parameter
if update_cron_workflow_trigger_request is not None:
_body_params = update_cron_workflow_trigger_request
# set the HTTP header `Accept`
if "Accept" not in _header_params:
_header_params["Accept"] = self.api_client.select_header_accept(
["application/json"]
)
# set the HTTP header `Content-Type`
if _content_type:
_header_params["Content-Type"] = _content_type
else:
_default_content_type = self.api_client.select_header_content_type(
["application/json"]
)
if _default_content_type is not None:
_header_params["Content-Type"] = _default_content_type
# authentication setting
_auth_settings: List[str] = ["cookieAuth", "bearerAuth"]
return self.api_client.param_serialize(
method="PATCH",
resource_path="/api/v1/tenants/{tenant}/workflows/crons/{cron-workflow}",
path_params=_path_params,
query_params=_query_params,
header_params=_header_params,
body=_body_params,
post_params=_form_params,
files=_files,
auth_settings=_auth_settings,
collection_formats=_collection_formats,
_host=_host,
_request_auth=_request_auth,
)
@validate_call
def workflow_delete(
self,

View File

@@ -640,6 +640,414 @@ class WorkflowRunsApi:
_request_auth=_request_auth,
)
@validate_call
def v1_workflow_run_external_ids_list(
self,
tenant: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The tenant id"
),
],
since: Annotated[datetime, Field(description="The earliest date to filter by")],
statuses: Annotated[
Optional[List[V1TaskStatus]],
Field(description="A list of statuses to filter by"),
] = None,
until: Annotated[
Optional[datetime], Field(description="The latest date to filter by")
] = None,
additional_metadata: Annotated[
Optional[List[StrictStr]],
Field(description="Additional metadata k-v pairs to filter by"),
] = None,
workflow_ids: Annotated[
Optional[
List[Annotated[str, Field(min_length=36, strict=True, max_length=36)]]
],
Field(description="The workflow ids to find runs for"),
] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]
],
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> List[str]:
"""List workflow run external ids
Lists external ids for workflow runs matching filters
:param tenant: The tenant id (required)
:type tenant: str
:param since: The earliest date to filter by (required)
:type since: datetime
:param statuses: A list of statuses to filter by
:type statuses: List[V1TaskStatus]
:param until: The latest date to filter by
:type until: datetime
:param additional_metadata: Additional metadata k-v pairs to filter by
:type additional_metadata: List[str]
:param workflow_ids: The workflow ids to find runs for
:type workflow_ids: List[str]
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._v1_workflow_run_external_ids_list_serialize(
tenant=tenant,
since=since,
statuses=statuses,
until=until,
additional_metadata=additional_metadata,
workflow_ids=workflow_ids,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index,
)
_response_types_map: Dict[str, Optional[str]] = {
"200": "List[str]",
"400": "APIErrors",
"403": "APIErrors",
"501": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
)
response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
).data
@validate_call
def v1_workflow_run_external_ids_list_with_http_info(
self,
tenant: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The tenant id"
),
],
since: Annotated[datetime, Field(description="The earliest date to filter by")],
statuses: Annotated[
Optional[List[V1TaskStatus]],
Field(description="A list of statuses to filter by"),
] = None,
until: Annotated[
Optional[datetime], Field(description="The latest date to filter by")
] = None,
additional_metadata: Annotated[
Optional[List[StrictStr]],
Field(description="Additional metadata k-v pairs to filter by"),
] = None,
workflow_ids: Annotated[
Optional[
List[Annotated[str, Field(min_length=36, strict=True, max_length=36)]]
],
Field(description="The workflow ids to find runs for"),
] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]
],
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> ApiResponse[List[str]]:
"""List workflow run external ids
Lists external ids for workflow runs matching filters
:param tenant: The tenant id (required)
:type tenant: str
:param since: The earliest date to filter by (required)
:type since: datetime
:param statuses: A list of statuses to filter by
:type statuses: List[V1TaskStatus]
:param until: The latest date to filter by
:type until: datetime
:param additional_metadata: Additional metadata k-v pairs to filter by
:type additional_metadata: List[str]
:param workflow_ids: The workflow ids to find runs for
:type workflow_ids: List[str]
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._v1_workflow_run_external_ids_list_serialize(
tenant=tenant,
since=since,
statuses=statuses,
until=until,
additional_metadata=additional_metadata,
workflow_ids=workflow_ids,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index,
)
_response_types_map: Dict[str, Optional[str]] = {
"200": "List[str]",
"400": "APIErrors",
"403": "APIErrors",
"501": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
)
response_data.read()
return self.api_client.response_deserialize(
response_data=response_data,
response_types_map=_response_types_map,
)
@validate_call
def v1_workflow_run_external_ids_list_without_preload_content(
self,
tenant: Annotated[
str,
Field(
min_length=36, strict=True, max_length=36, description="The tenant id"
),
],
since: Annotated[datetime, Field(description="The earliest date to filter by")],
statuses: Annotated[
Optional[List[V1TaskStatus]],
Field(description="A list of statuses to filter by"),
] = None,
until: Annotated[
Optional[datetime], Field(description="The latest date to filter by")
] = None,
additional_metadata: Annotated[
Optional[List[StrictStr]],
Field(description="Additional metadata k-v pairs to filter by"),
] = None,
workflow_ids: Annotated[
Optional[
List[Annotated[str, Field(min_length=36, strict=True, max_length=36)]]
],
Field(description="The workflow ids to find runs for"),
] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)]
],
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> RESTResponseType:
"""List workflow run external ids
Lists external ids for workflow runs matching filters
:param tenant: The tenant id (required)
:type tenant: str
:param since: The earliest date to filter by (required)
:type since: datetime
:param statuses: A list of statuses to filter by
:type statuses: List[V1TaskStatus]
:param until: The latest date to filter by
:type until: datetime
:param additional_metadata: Additional metadata k-v pairs to filter by
:type additional_metadata: List[str]
:param workflow_ids: The workflow ids to find runs for
:type workflow_ids: List[str]
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:type _request_timeout: int, tuple(int, int), optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the
authentication in the spec for a single request.
:type _request_auth: dict, optional
:param _content_type: force content-type for the request.
:type _content_type: str, Optional
:param _headers: set to override the headers for a single
request; this effectively ignores the headers
in the spec for a single request.
:type _headers: dict, optional
:param _host_index: set to override the host_index for a single
request; this effectively ignores the host_index
in the spec for a single request.
:type _host_index: int, optional
:return: Returns the result object.
""" # noqa: E501
_param = self._v1_workflow_run_external_ids_list_serialize(
tenant=tenant,
since=since,
statuses=statuses,
until=until,
additional_metadata=additional_metadata,
workflow_ids=workflow_ids,
_request_auth=_request_auth,
_content_type=_content_type,
_headers=_headers,
_host_index=_host_index,
)
_response_types_map: Dict[str, Optional[str]] = {
"200": "List[str]",
"400": "APIErrors",
"403": "APIErrors",
"501": "APIErrors",
}
response_data = self.api_client.call_api(
*_param, _request_timeout=_request_timeout
)
return response_data.response
def _v1_workflow_run_external_ids_list_serialize(
self,
tenant,
since,
statuses,
until,
additional_metadata,
workflow_ids,
_request_auth,
_content_type,
_headers,
_host_index,
) -> RequestSerialized:
_host = None
_collection_formats: Dict[str, str] = {
"statuses": "multi",
"additional_metadata": "multi",
"workflow_ids": "multi",
}
_path_params: Dict[str, str] = {}
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
if tenant is not None:
_path_params["tenant"] = tenant
# process the query parameters
if statuses is not None:
_query_params.append(("statuses", statuses))
if since is not None:
if isinstance(since, datetime):
_query_params.append(
(
"since",
since.strftime(self.api_client.configuration.datetime_format),
)
)
else:
_query_params.append(("since", since))
if until is not None:
if isinstance(until, datetime):
_query_params.append(
(
"until",
until.strftime(self.api_client.configuration.datetime_format),
)
)
else:
_query_params.append(("until", until))
if additional_metadata is not None:
_query_params.append(("additional_metadata", additional_metadata))
if workflow_ids is not None:
_query_params.append(("workflow_ids", workflow_ids))
# process the header parameters
# process the form parameters
# process the body parameter
# set the HTTP header `Accept`
if "Accept" not in _header_params:
_header_params["Accept"] = self.api_client.select_header_accept(
["application/json"]
)
# authentication setting
_auth_settings: List[str] = ["cookieAuth", "bearerAuth"]
return self.api_client.param_serialize(
method="GET",
resource_path="/api/v1/stable/tenants/{tenant}/workflow-runs/external-ids",
path_params=_path_params,
query_params=_query_params,
header_params=_header_params,
body=_body_params,
post_params=_form_params,
files=_files,
auth_settings=_auth_settings,
collection_formats=_collection_formats,
_host=_host,
_request_auth=_request_auth,
)
@validate_call
def v1_workflow_run_get(
self,

View File

@@ -121,6 +121,7 @@ AuthSettings = TypedDict(
{
"bearerAuth": BearerAuthSetting,
"cookieAuth": APIKeyAuthSetting,
"customAuth": BearerAuthSetting,
},
total=False,
)
@@ -537,6 +538,13 @@ class Configuration:
"cookieAuth",
),
}
if self.access_token is not None:
auth["customAuth"] = {
"type": "bearer",
"in": "header",
"key": "Authorization",
"value": "Bearer " + self.access_token,
}
return auth
def to_debug_report(self) -> str:

View File

@@ -112,6 +112,7 @@ from hatchet_sdk.clients.rest.models.rate_limit_order_by_field import (
RateLimitOrderByField,
)
from hatchet_sdk.clients.rest.models.recent_step_runs import RecentStepRuns
from hatchet_sdk.clients.rest.models.registered_workflow import RegisteredWorkflow
from hatchet_sdk.clients.rest.models.reject_invite_request import RejectInviteRequest
from hatchet_sdk.clients.rest.models.replay_event_request import ReplayEventRequest
from hatchet_sdk.clients.rest.models.replay_workflow_runs_request import (
@@ -158,6 +159,7 @@ from hatchet_sdk.clients.rest.models.tenant_alert_email_group_list import (
from hatchet_sdk.clients.rest.models.tenant_alerting_settings import (
TenantAlertingSettings,
)
from hatchet_sdk.clients.rest.models.tenant_environment import TenantEnvironment
from hatchet_sdk.clients.rest.models.tenant_invite import TenantInvite
from hatchet_sdk.clients.rest.models.tenant_invite_list import TenantInviteList
from hatchet_sdk.clients.rest.models.tenant_list import TenantList
@@ -176,12 +178,18 @@ from hatchet_sdk.clients.rest.models.tenant_version import TenantVersion
from hatchet_sdk.clients.rest.models.trigger_workflow_run_request import (
TriggerWorkflowRunRequest,
)
from hatchet_sdk.clients.rest.models.update_cron_workflow_trigger_request import (
UpdateCronWorkflowTriggerRequest,
)
from hatchet_sdk.clients.rest.models.update_tenant_alert_email_group_request import (
UpdateTenantAlertEmailGroupRequest,
)
from hatchet_sdk.clients.rest.models.update_tenant_invite_request import (
UpdateTenantInviteRequest,
)
from hatchet_sdk.clients.rest.models.update_tenant_member_request import (
UpdateTenantMemberRequest,
)
from hatchet_sdk.clients.rest.models.update_tenant_request import UpdateTenantRequest
from hatchet_sdk.clients.rest.models.update_worker_request import UpdateWorkerRequest
from hatchet_sdk.clients.rest.models.user import User
@@ -252,6 +260,9 @@ from hatchet_sdk.clients.rest.models.v1_trigger_workflow_run_request import (
from hatchet_sdk.clients.rest.models.v1_update_filter_request import (
V1UpdateFilterRequest,
)
from hatchet_sdk.clients.rest.models.v1_update_webhook_request import (
V1UpdateWebhookRequest,
)
from hatchet_sdk.clients.rest.models.v1_webhook import V1Webhook
from hatchet_sdk.clients.rest.models.v1_webhook_api_key_auth import V1WebhookAPIKeyAuth
from hatchet_sdk.clients.rest.models.v1_webhook_auth_type import V1WebhookAuthType
@@ -264,9 +275,6 @@ from hatchet_sdk.clients.rest.models.v1_webhook_hmac_encoding import (
V1WebhookHMACEncoding,
)
from hatchet_sdk.clients.rest.models.v1_webhook_list import V1WebhookList
from hatchet_sdk.clients.rest.models.v1_webhook_receive200_response import (
V1WebhookReceive200Response,
)
from hatchet_sdk.clients.rest.models.v1_webhook_source_name import V1WebhookSourceName
from hatchet_sdk.clients.rest.models.v1_workflow_run import V1WorkflowRun
from hatchet_sdk.clients.rest.models.v1_workflow_run_details import V1WorkflowRunDetails

View File

@@ -22,6 +22,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Set
from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing_extensions import Self
from hatchet_sdk.clients.rest.models.tenant_environment import TenantEnvironment
from hatchet_sdk.clients.rest.models.tenant_ui_version import TenantUIVersion
from hatchet_sdk.clients.rest.models.tenant_version import TenantVersion
@@ -43,7 +44,22 @@ class CreateTenantRequest(BaseModel):
description="The engine version of the tenant. Defaults to V0.",
alias="engineVersion",
)
__properties: ClassVar[List[str]] = ["name", "slug", "uiVersion", "engineVersion"]
environment: Optional[TenantEnvironment] = Field(
default=None, description="The environment type of the tenant."
)
onboarding_data: Optional[Dict[str, Any]] = Field(
default=None,
description="Additional onboarding data to store with the tenant.",
alias="onboardingData",
)
__properties: ClassVar[List[str]] = [
"name",
"slug",
"uiVersion",
"engineVersion",
"environment",
"onboardingData",
]
model_config = ConfigDict(
populate_by_name=True,
@@ -99,6 +115,8 @@ class CreateTenantRequest(BaseModel):
"slug": obj.get("slug"),
"uiVersion": obj.get("uiVersion"),
"engineVersion": obj.get("engineVersion"),
"environment": obj.get("environment"),
"onboardingData": obj.get("onboardingData"),
}
)
return _obj

View File

@@ -0,0 +1,86 @@
# coding: utf-8
"""
Hatchet API
The Hatchet API
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import json
import pprint
import re # noqa: F401
from typing import Any, ClassVar, Dict, List, Optional, Set
from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing_extensions import Self
class RegisteredWorkflow(BaseModel):
"""
RegisteredWorkflow
""" # noqa: E501
id: StrictStr = Field(description="The workflow id registered on this worker.")
name: StrictStr = Field(
description="The name of the workflow registered on this worker."
)
__properties: ClassVar[List[str]] = ["id", "name"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of RegisteredWorkflow from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of RegisteredWorkflow from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({"id": obj.get("id"), "name": obj.get("name")})
return _obj

View File

@@ -23,6 +23,7 @@ from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr
from typing_extensions import Self
from hatchet_sdk.clients.rest.models.api_resource_meta import APIResourceMeta
from hatchet_sdk.clients.rest.models.tenant_environment import TenantEnvironment
from hatchet_sdk.clients.rest.models.tenant_ui_version import TenantUIVersion
from hatchet_sdk.clients.rest.models.tenant_version import TenantVersion
@@ -49,6 +50,9 @@ class Tenant(BaseModel):
ui_version: Optional[TenantUIVersion] = Field(
default=None, description="The UI of the tenant.", alias="uiVersion"
)
environment: Optional[TenantEnvironment] = Field(
default=None, description="The environment type of the tenant."
)
__properties: ClassVar[List[str]] = [
"metadata",
"name",
@@ -57,6 +61,7 @@ class Tenant(BaseModel):
"alertMemberEmails",
"version",
"uiVersion",
"environment",
]
model_config = ConfigDict(
@@ -123,6 +128,7 @@ class Tenant(BaseModel):
"alertMemberEmails": obj.get("alertMemberEmails"),
"version": obj.get("version"),
"uiVersion": obj.get("uiVersion"),
"environment": obj.get("environment"),
}
)
return _obj

View File

@@ -0,0 +1,38 @@
# coding: utf-8
"""
Hatchet API
The Hatchet API
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import json
from enum import Enum
from typing_extensions import Self
class TenantEnvironment(str, Enum):
"""
TenantEnvironment
"""
"""
allowed enum values
"""
LOCAL = "local"
DEVELOPMENT = "development"
PRODUCTION = "production"
@classmethod
def from_json(cls, json_str: str) -> Self:
"""Create an instance of TenantEnvironment from a JSON string"""
return cls(json.loads(json_str))

View File

@@ -0,0 +1,83 @@
# coding: utf-8
"""
Hatchet API
The Hatchet API
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import json
import pprint
import re # noqa: F401
from typing import Any, ClassVar, Dict, List, Optional, Set
from pydantic import BaseModel, ConfigDict, StrictBool
from typing_extensions import Self
class UpdateCronWorkflowTriggerRequest(BaseModel):
"""
UpdateCronWorkflowTriggerRequest
""" # noqa: E501
enabled: Optional[StrictBool] = None
__properties: ClassVar[List[str]] = ["enabled"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of UpdateCronWorkflowTriggerRequest from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of UpdateCronWorkflowTriggerRequest from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({"enabled": obj.get("enabled")})
return _obj

View File

@@ -0,0 +1,85 @@
# coding: utf-8
"""
Hatchet API
The Hatchet API
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import json
import pprint
import re # noqa: F401
from typing import Any, ClassVar, Dict, List, Optional, Set
from pydantic import BaseModel, ConfigDict, Field
from typing_extensions import Self
from hatchet_sdk.clients.rest.models.tenant_member_role import TenantMemberRole
class UpdateTenantMemberRequest(BaseModel):
"""
UpdateTenantMemberRequest
""" # noqa: E501
role: TenantMemberRole = Field(description="The role of the user in the tenant.")
__properties: ClassVar[List[str]] = ["role"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of UpdateTenantMemberRequest from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of UpdateTenantMemberRequest from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({"role": obj.get("role")})
return _obj

View File

@@ -19,7 +19,7 @@ import pprint
import re # noqa: F401
from typing import Any, ClassVar, Dict, List, Optional, Set
from pydantic import BaseModel, ConfigDict, Field, StrictStr
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr
from typing_extensions import Annotated, Self
from hatchet_sdk.clients.rest.models.api_resource_meta import APIResourceMeta
@@ -50,6 +50,11 @@ class V1Filter(BaseModel):
payload: Dict[str, Any] = Field(
description="Additional payload data associated with the filter"
)
is_declarative: Optional[StrictBool] = Field(
default=None,
description="Whether the filter is declarative (true) or programmatic (false)",
alias="isDeclarative",
)
__properties: ClassVar[List[str]] = [
"metadata",
"tenantId",
@@ -57,6 +62,7 @@ class V1Filter(BaseModel):
"scope",
"expression",
"payload",
"isDeclarative",
]
model_config = ConfigDict(
@@ -122,6 +128,7 @@ class V1Filter(BaseModel):
"scope": obj.get("scope"),
"expression": obj.get("expression"),
"payload": obj.get("payload"),
"isDeclarative": obj.get("isDeclarative"),
}
)
return _obj

View File

@@ -0,0 +1,86 @@
# coding: utf-8
"""
Hatchet API
The Hatchet API
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import json
import pprint
import re # noqa: F401
from typing import Any, ClassVar, Dict, List, Optional, Set
from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing_extensions import Self
class V1UpdateWebhookRequest(BaseModel):
"""
V1UpdateWebhookRequest
""" # noqa: E501
event_key_expression: StrictStr = Field(
description="The CEL expression to use for the event key. This is used to create the event key from the webhook payload.",
alias="eventKeyExpression",
)
__properties: ClassVar[List[str]] = ["eventKeyExpression"]
model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of V1UpdateWebhookRequest from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([])
_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of V1UpdateWebhookRequest from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({"eventKeyExpression": obj.get("eventKeyExpression")})
return _obj

View File

@@ -31,6 +31,8 @@ class V1WebhookSourceName(str, Enum):
GENERIC = "GENERIC"
GITHUB = "GITHUB"
STRIPE = "STRIPE"
SLACK = "SLACK"
LINEAR = "LINEAR"
@classmethod
def from_json(cls, json_str: str) -> Self:

View File

@@ -25,6 +25,7 @@ from typing_extensions import Annotated, Self
from hatchet_sdk.clients.rest.models.api_resource_meta import APIResourceMeta
from hatchet_sdk.clients.rest.models.recent_step_runs import RecentStepRuns
from hatchet_sdk.clients.rest.models.registered_workflow import RegisteredWorkflow
from hatchet_sdk.clients.rest.models.semaphore_slots import SemaphoreSlots
from hatchet_sdk.clients.rest.models.worker_label import WorkerLabel
from hatchet_sdk.clients.rest.models.worker_runtime_info import WorkerRuntimeInfo
@@ -52,6 +53,11 @@ class Worker(BaseModel):
actions: Optional[List[StrictStr]] = Field(
default=None, description="The actions this worker can perform."
)
registered_workflows: Optional[List[RegisteredWorkflow]] = Field(
default=None,
description="The workflow ids registered on this worker.",
alias="registeredWorkflows",
)
slots: Optional[List[SemaphoreSlots]] = Field(
default=None, description="The semaphore slot state for the worker."
)
@@ -97,6 +103,7 @@ class Worker(BaseModel):
"lastHeartbeatAt",
"lastListenerEstablished",
"actions",
"registeredWorkflows",
"slots",
"recentStepRuns",
"status",
@@ -161,6 +168,13 @@ class Worker(BaseModel):
# override the default output from pydantic by calling `to_dict()` of metadata
if self.metadata:
_dict["metadata"] = self.metadata.to_dict()
# override the default output from pydantic by calling `to_dict()` of each item in registered_workflows (list)
_items = []
if self.registered_workflows:
for _item_registered_workflows in self.registered_workflows:
if _item_registered_workflows:
_items.append(_item_registered_workflows.to_dict())
_dict["registeredWorkflows"] = _items
# override the default output from pydantic by calling `to_dict()` of each item in slots (list)
_items = []
if self.slots:
@@ -208,6 +222,14 @@ class Worker(BaseModel):
"lastHeartbeatAt": obj.get("lastHeartbeatAt"),
"lastListenerEstablished": obj.get("lastListenerEstablished"),
"actions": obj.get("actions"),
"registeredWorkflows": (
[
RegisteredWorkflow.from_dict(_item)
for _item in obj["registeredWorkflows"]
]
if obj.get("registeredWorkflows") is not None
else None
),
"slots": (
[SemaphoreSlots.from_dict(_item) for _item in obj["slots"]]
if obj.get("slots") is not None

View File

@@ -1,4 +1,5 @@
import asyncio
import time
from collections.abc import AsyncIterator
from datetime import datetime, timedelta, timezone
from typing import TYPE_CHECKING, Literal, overload
@@ -32,6 +33,7 @@ from hatchet_sdk.clients.v1.api_client import (
from hatchet_sdk.config import ClientConfig
from hatchet_sdk.utils.aio import gather_max_concurrency
from hatchet_sdk.utils.datetimes import partition_date_range
from hatchet_sdk.utils.iterables import create_chunks
from hatchet_sdk.utils.typing import JSONSerializableMapping
if TYPE_CHECKING:
@@ -179,6 +181,216 @@ class RunsClient(BaseRestClient):
"""
return await asyncio.to_thread(self.get_status, workflow_run_id)
def _perform_action_with_pagination(
self,
action: Literal["cancel", "replay"],
statuses: list[V1TaskStatus],
sleep_time: int = 3,
chunk_size: int = 500,
since: datetime | None = None,
until: datetime | None = None,
additional_metadata: dict[str, str] | None = None,
workflow_ids: list[str] | None = None,
) -> None:
"""
Perform a bulk action (cancel or replay) on runs matching the specified filters in chunks.
The motivation for this method is to provide an easy way to perform bulk operations by filters over a larger number of runs than
the API would normally be able to handle, with automatic pagination and chunking to help limit the pressure on the API.
This method first pulls the IDs of the runs from the API, and then feeds them back to the API in chunks.
:param action: The action to perform, either "cancel" or "replay".
:param statuses: The statuses to filter runs by.
:param sleep_time: The time to sleep between processing chunks, in seconds.
:param chunk_size: The maximum number of run IDs to process in each chunk.
:param since: The start time for filtering runs.
:param until: The end time for filtering runs.
:param additional_metadata: Additional metadata to filter runs by.
:param workflow_ids: The workflow IDs to filter runs by.
"""
until = until or datetime.now(tz=timezone.utc)
since = since or (until - timedelta(days=1))
with self.client() as client:
external_ids = self._wra(client).v1_workflow_run_external_ids_list(
tenant=self.client_config.tenant_id,
since=since,
until=until,
additional_metadata=maybe_additional_metadata_to_kv(
additional_metadata
),
statuses=statuses,
workflow_ids=workflow_ids,
)
chunks = list(create_chunks(external_ids, chunk_size))
func = self.bulk_cancel if action == "cancel" else self.bulk_replay
for ix, chunk in enumerate(chunks):
self.client_config.logger.info(
f"processing chunk {ix + 1}/{len(chunks)} of {len(chunk)} ids" # noqa: G004
)
opts = BulkCancelReplayOpts(ids=chunk)
func(opts=opts)
time.sleep(sleep_time)
def bulk_replay_by_filters_with_pagination(
self,
sleep_time: int = 3,
chunk_size: int = 500,
since: datetime | None = None,
until: datetime | None = None,
statuses: list[V1TaskStatus] | None = None,
additional_metadata: dict[str, str] | None = None,
workflow_ids: list[str] | None = None,
) -> None:
"""
Replay runs matching the specified filters in chunks.
The motivation for this method is to provide an easy way to perform bulk operations by filters over a larger number of runs than
the API would normally be able to handle, with automatic pagination and chunking to help limit the pressure on the API.
This method first pulls the IDs of the runs from the API, and then feeds them back to the API in chunks.
:param sleep_time: The time to sleep between processing chunks, in seconds.
:param chunk_size: The maximum number of run IDs to process in each chunk.
:param since: The start time for filtering runs.
:param until: The end time for filtering runs.
:param statuses: The statuses to filter runs by.
:param additional_metadata: Additional metadata to filter runs by.
:param workflow_ids: The workflow IDs to filter runs by.
"""
self._perform_action_with_pagination(
since=since,
action="replay",
sleep_time=sleep_time,
chunk_size=chunk_size,
until=until,
statuses=statuses or [V1TaskStatus.FAILED, V1TaskStatus.CANCELLED],
additional_metadata=additional_metadata,
workflow_ids=workflow_ids,
)
def bulk_cancel_by_filters_with_pagination(
self,
sleep_time: int = 3,
chunk_size: int = 500,
since: datetime | None = None,
until: datetime | None = None,
statuses: list[V1TaskStatus] | None = None,
additional_metadata: dict[str, str] | None = None,
workflow_ids: list[str] | None = None,
) -> None:
"""
Cancel runs matching the specified filters in chunks.
The motivation for this method is to provide an easy way to perform bulk operations by filters over a larger number of runs than
the API would normally be able to handle, with automatic pagination and chunking to help limit the pressure on the API.
This method first pulls the IDs of the runs from the API, and then feeds them back to the API in chunks.
:param sleep_time: The time to sleep between processing chunks, in seconds.
:param chunk_size: The maximum number of run IDs to process in each chunk.
:param since: The start time for filtering runs.
:param until: The end time for filtering runs.
:param statuses: The statuses to filter runs by.
:param additional_metadata: Additional metadata to filter runs by.
:param workflow_ids: The workflow IDs to filter runs by.
"""
self._perform_action_with_pagination(
since=since,
action="cancel",
sleep_time=sleep_time,
chunk_size=chunk_size,
until=until,
statuses=statuses or [V1TaskStatus.RUNNING, V1TaskStatus.QUEUED],
additional_metadata=additional_metadata,
workflow_ids=workflow_ids,
)
async def aio_bulk_replay_by_filters_with_pagination(
self,
sleep_time: int = 3,
chunk_size: int = 500,
since: datetime | None = None,
until: datetime | None = None,
statuses: list[V1TaskStatus] | None = None,
additional_metadata: dict[str, str] | None = None,
workflow_ids: list[str] | None = None,
) -> None:
"""
Replay runs matching the specified filters in chunks.
The motivation for this method is to provide an easy way to perform bulk operations by filters over a larger number of runs than
the API would normally be able to handle, with automatic pagination and chunking to help limit the pressure on the API.
This method first pulls the IDs of the runs from the API, and then feeds them back to the API in chunks.
:param sleep_time: The time to sleep between processing chunks, in seconds.
:param chunk_size: The maximum number of run IDs to process in each chunk.
:param since: The start time for filtering runs.
:param until: The end time for filtering runs.
:param statuses: The statuses to filter runs by.
:param additional_metadata: Additional metadata to filter runs by.
:param workflow_ids: The workflow IDs to filter runs by.
"""
await asyncio.to_thread(
self._perform_action_with_pagination,
since=since,
action="replay",
sleep_time=sleep_time,
chunk_size=chunk_size,
until=until,
statuses=statuses or [V1TaskStatus.FAILED, V1TaskStatus.CANCELLED],
additional_metadata=additional_metadata,
workflow_ids=workflow_ids,
)
async def aio_bulk_cancel_by_filters_with_pagination(
self,
sleep_time: int = 3,
chunk_size: int = 500,
since: datetime | None = None,
until: datetime | None = None,
statuses: list[V1TaskStatus] | None = None,
additional_metadata: dict[str, str] | None = None,
workflow_ids: list[str] | None = None,
) -> None:
"""
Cancel runs matching the specified filters in chunks.
The motivation for this method is to provide an easy way to perform bulk operations by filters over a larger number of runs than
the API would normally be able to handle, with automatic pagination and chunking to help limit the pressure on the API.
This method first pulls the IDs of the runs from the API, and then feeds them back to the API in chunks.
:param sleep_time: The time to sleep between processing chunks, in seconds.
:param chunk_size: The maximum number of run IDs to process in each chunk.
:param since: The start time for filtering runs.
:param until: The end time for filtering runs.
:param statuses: The statuses to filter runs by.
:param additional_metadata: Additional metadata to filter runs by.
:param workflow_ids: The workflow IDs to filter runs by.
"""
await asyncio.to_thread(
self._perform_action_with_pagination,
since=since,
action="cancel",
sleep_time=sleep_time,
chunk_size=chunk_size,
until=until,
statuses=statuses or [V1TaskStatus.RUNNING, V1TaskStatus.QUEUED],
additional_metadata=additional_metadata,
workflow_ids=workflow_ids,
)
@retry
def list_with_pagination(
self,

View File

@@ -0,0 +1,9 @@
from collections.abc import Generator
from typing import TypeVar
T = TypeVar("T")
def create_chunks(xs: list[T], n: int) -> Generator[list[T], None, None]:
for i in range(0, len(xs), n):
yield xs[i : i + n]

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "hatchet-sdk"
version = "1.20.0"
version = "1.20.1"
description = ""
authors = ["Alexander Belanger <alexander@hatchet.run>"]
readme = "README.md"