scrapely-client-python 1.0.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 scrapely-client-python might be problematic. Click here for more details.

Files changed (65) hide show
  1. scrapely_client/__init__.py +30 -0
  2. scrapely_client/_charging.py +186 -0
  3. scrapely_client/_client_registry.py +136 -0
  4. scrapely_client/_consts.py +96 -0
  5. scrapely_client/_docs.py +37 -0
  6. scrapely_client/_literals.py +539 -0
  7. scrapely_client/_logging.py +180 -0
  8. scrapely_client/_models.py +4172 -0
  9. scrapely_client/_pagination.py +220 -0
  10. scrapely_client/_resource_clients/__init__.py +84 -0
  11. scrapely_client/_resource_clients/_resource_client.py +567 -0
  12. scrapely_client/_resource_clients/actor.py +1042 -0
  13. scrapely_client/_resource_clients/actor_collection.py +377 -0
  14. scrapely_client/_resource_clients/actor_env_var.py +154 -0
  15. scrapely_client/_resource_clients/actor_env_var_collection.py +165 -0
  16. scrapely_client/_resource_clients/actor_version.py +254 -0
  17. scrapely_client/_resource_clients/actor_version_collection.py +232 -0
  18. scrapely_client/_resource_clients/build.py +244 -0
  19. scrapely_client/_resource_clients/build_collection.py +164 -0
  20. scrapely_client/_resource_clients/dataset.py +1151 -0
  21. scrapely_client/_resource_clients/dataset_collection.py +244 -0
  22. scrapely_client/_resource_clients/key_value_store.py +906 -0
  23. scrapely_client/_resource_clients/key_value_store_collection.py +243 -0
  24. scrapely_client/_resource_clients/log.py +225 -0
  25. scrapely_client/_resource_clients/request_queue.py +1167 -0
  26. scrapely_client/_resource_clients/request_queue_collection.py +240 -0
  27. scrapely_client/_resource_clients/run.py +875 -0
  28. scrapely_client/_resource_clients/run_collection.py +226 -0
  29. scrapely_client/_resource_clients/schedule.py +243 -0
  30. scrapely_client/_resource_clients/schedule_collection.py +260 -0
  31. scrapely_client/_resource_clients/store_collection.py +242 -0
  32. scrapely_client/_resource_clients/task.py +793 -0
  33. scrapely_client/_resource_clients/task_collection.py +322 -0
  34. scrapely_client/_resource_clients/user.py +262 -0
  35. scrapely_client/_resource_clients/webhook.py +292 -0
  36. scrapely_client/_resource_clients/webhook_collection.py +281 -0
  37. scrapely_client/_resource_clients/webhook_dispatch.py +84 -0
  38. scrapely_client/_resource_clients/webhook_dispatch_collection.py +158 -0
  39. scrapely_client/_scrapely_client.py +837 -0
  40. scrapely_client/_statistics.py +29 -0
  41. scrapely_client/_status_message_watcher.py +197 -0
  42. scrapely_client/_streamed_log.py +250 -0
  43. scrapely_client/_typeddicts.py +408 -0
  44. scrapely_client/_utils/__init__.py +0 -0
  45. scrapely_client/_utils/crypto.py +87 -0
  46. scrapely_client/_utils/encoding.py +133 -0
  47. scrapely_client/_utils/errors.py +33 -0
  48. scrapely_client/_utils/http.py +137 -0
  49. scrapely_client/_utils/time.py +32 -0
  50. scrapely_client/_utils/try_import.py +61 -0
  51. scrapely_client/errors.py +190 -0
  52. scrapely_client/http_clients/__init__.py +10 -0
  53. scrapely_client/http_clients/_base.py +430 -0
  54. scrapely_client/http_clients/_impit.py +598 -0
  55. scrapely_client/http_compressors/__init__.py +18 -0
  56. scrapely_client/http_compressors/_base.py +25 -0
  57. scrapely_client/http_compressors/_brotli.py +38 -0
  58. scrapely_client/http_compressors/_gzip.py +38 -0
  59. scrapely_client/http_compressors/_resolve.py +38 -0
  60. scrapely_client/py.typed +0 -0
  61. scrapely_client/types.py +52 -0
  62. scrapely_client_python-1.0.0.dist-info/METADATA +244 -0
  63. scrapely_client_python-1.0.0.dist-info/RECORD +65 -0
  64. scrapely_client_python-1.0.0.dist-info/WHEEL +4 -0
  65. scrapely_client_python-1.0.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,292 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from pydantic import AnyUrl
6
+
7
+ from scrapely_client._docs import docs_group
8
+ from scrapely_client._models import (
9
+ TestWebhookResponse,
10
+ Webhook,
11
+ WebhookCondition,
12
+ WebhookDispatch,
13
+ WebhookResponse,
14
+ WebhookUpdate,
15
+ )
16
+ from scrapely_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync
17
+ from scrapely_client._utils.http import response_to_dict
18
+
19
+ if TYPE_CHECKING:
20
+ from scrapely_client._literals import WebhookEventType
21
+ from scrapely_client._resource_clients import WebhookDispatchCollectionClient, WebhookDispatchCollectionClientAsync
22
+ from scrapely_client.types import Timeout
23
+
24
+
25
+ @docs_group('Resource clients')
26
+ class WebhookClient(ResourceClient):
27
+ """Sub-client for managing a specific webhook.
28
+
29
+ Provides methods to manage a specific webhook, e.g. get, update, or delete it. Obtain an instance via an
30
+ appropriate method on the `ApifyClient` class.
31
+ """
32
+
33
+ def __init__(
34
+ self,
35
+ *,
36
+ resource_id: str,
37
+ resource_path: str = 'webhooks',
38
+ **kwargs: Any,
39
+ ) -> None:
40
+ super().__init__(
41
+ resource_id=resource_id,
42
+ resource_path=resource_path,
43
+ **kwargs,
44
+ )
45
+
46
+ def get(self, *, timeout: Timeout = 'short') -> Webhook | None:
47
+ """Retrieve the webhook.
48
+
49
+
50
+ Args:
51
+ timeout: Timeout for the API HTTP request.
52
+
53
+ Returns:
54
+ The retrieved webhook, or None if it does not exist.
55
+ """
56
+ result = self._get(timeout=timeout)
57
+ if result is None:
58
+ return None
59
+ return WebhookResponse.model_validate(result).data
60
+
61
+ def update(
62
+ self,
63
+ *,
64
+ event_types: list[WebhookEventType] | None = None,
65
+ request_url: str | None = None,
66
+ payload_template: str | None = None,
67
+ headers_template: str | None = None,
68
+ actor_id: str | None = None,
69
+ actor_task_id: str | None = None,
70
+ actor_run_id: str | None = None,
71
+ ignore_ssl_errors: bool | None = None,
72
+ do_not_retry: bool | None = None,
73
+ is_ad_hoc: bool | None = None,
74
+ timeout: Timeout = 'short',
75
+ ) -> Webhook:
76
+ """Update the webhook.
77
+
78
+
79
+ Args:
80
+ event_types: List of event types that should trigger the webhook. At least one is required.
81
+ request_url: URL that will be invoked once the webhook is triggered.
82
+ payload_template: Specification of the payload that will be sent to request_url.
83
+ headers_template: Headers that will be sent to the request_url.
84
+ actor_id: Id of the Actor whose runs should trigger the webhook.
85
+ actor_task_id: Id of the Actor task whose runs should trigger the webhook.
86
+ actor_run_id: Id of the Actor run which should trigger the webhook.
87
+ ignore_ssl_errors: Whether the webhook should ignore SSL errors returned by request_url.
88
+ do_not_retry: Whether the webhook should retry sending the payload to request_url upon failure.
89
+ is_ad_hoc: Set to True if you want the webhook to be triggered only the first time the condition
90
+ is fulfilled. Only applicable when actor_run_id is filled.
91
+ timeout: Timeout for the API HTTP request.
92
+
93
+ Returns:
94
+ The updated webhook.
95
+ """
96
+ webhook_update = WebhookUpdate(
97
+ event_types=list(event_types) if event_types is not None else None,
98
+ request_url=AnyUrl(request_url) if request_url is not None else None,
99
+ payload_template=payload_template,
100
+ headers_template=headers_template,
101
+ ignore_ssl_errors=ignore_ssl_errors,
102
+ do_not_retry=do_not_retry,
103
+ is_ad_hoc=is_ad_hoc if actor_run_id else None,
104
+ condition=WebhookCondition(
105
+ actor_run_id=actor_run_id,
106
+ actor_task_id=actor_task_id,
107
+ actor_id=actor_id,
108
+ ),
109
+ )
110
+ result = self._update(timeout=timeout, **webhook_update.model_dump(by_alias=True, exclude_none=True))
111
+ return WebhookResponse.model_validate(result).data
112
+
113
+ def delete(self, *, timeout: Timeout = 'short') -> None:
114
+ """Delete the webhook.
115
+
116
+
117
+ Args:
118
+ timeout: Timeout for the API HTTP request.
119
+ """
120
+ self._delete(timeout=timeout)
121
+
122
+ def test(self, *, timeout: Timeout = 'medium') -> WebhookDispatch:
123
+ """Test a webhook.
124
+
125
+ Creates a webhook dispatch with a dummy payload.
126
+
127
+
128
+ Args:
129
+ timeout: Timeout for the API HTTP request.
130
+
131
+ Returns:
132
+ The webhook dispatch created by the test.
133
+
134
+ Raises:
135
+ NotFoundError: If the webhook does not exist.
136
+ """
137
+ response = self._http_client.call(
138
+ url=self._build_url('test'),
139
+ method='POST',
140
+ params=self._build_params(),
141
+ timeout=timeout,
142
+ )
143
+
144
+ result = response_to_dict(response)
145
+ return TestWebhookResponse.model_validate(result).data
146
+
147
+ def dispatches(self) -> WebhookDispatchCollectionClient:
148
+ """Get dispatches of the webhook.
149
+
150
+
151
+ Returns:
152
+ A client allowing access to dispatches of this webhook using its list method.
153
+ """
154
+ return self._client_registry.webhook_dispatch_collection_client(
155
+ resource_path='dispatches',
156
+ **self._base_client_kwargs,
157
+ )
158
+
159
+
160
+ @docs_group('Resource clients')
161
+ class WebhookClientAsync(ResourceClientAsync):
162
+ """Sub-client for managing a specific webhook.
163
+
164
+ Provides methods to manage a specific webhook, e.g. get, update, or delete it. Obtain an instance via an
165
+ appropriate method on the `ApifyClientAsync` class.
166
+ """
167
+
168
+ def __init__(
169
+ self,
170
+ *,
171
+ resource_id: str,
172
+ resource_path: str = 'webhooks',
173
+ **kwargs: Any,
174
+ ) -> None:
175
+ super().__init__(
176
+ resource_id=resource_id,
177
+ resource_path=resource_path,
178
+ **kwargs,
179
+ )
180
+
181
+ async def get(self, *, timeout: Timeout = 'short') -> Webhook | None:
182
+ """Retrieve the webhook.
183
+
184
+
185
+ Args:
186
+ timeout: Timeout for the API HTTP request.
187
+
188
+ Returns:
189
+ The retrieved webhook, or None if it does not exist.
190
+ """
191
+ result = await self._get(timeout=timeout)
192
+ if result is None:
193
+ return None
194
+ return WebhookResponse.model_validate(result).data
195
+
196
+ async def update(
197
+ self,
198
+ *,
199
+ event_types: list[WebhookEventType] | None = None,
200
+ request_url: str | None = None,
201
+ payload_template: str | None = None,
202
+ headers_template: str | None = None,
203
+ actor_id: str | None = None,
204
+ actor_task_id: str | None = None,
205
+ actor_run_id: str | None = None,
206
+ ignore_ssl_errors: bool | None = None,
207
+ do_not_retry: bool | None = None,
208
+ is_ad_hoc: bool | None = None,
209
+ timeout: Timeout = 'short',
210
+ ) -> Webhook:
211
+ """Update the webhook.
212
+
213
+
214
+ Args:
215
+ event_types: List of event types that should trigger the webhook. At least one is required.
216
+ request_url: URL that will be invoked once the webhook is triggered.
217
+ payload_template: Specification of the payload that will be sent to request_url.
218
+ headers_template: Headers that will be sent to the request_url.
219
+ actor_id: Id of the Actor whose runs should trigger the webhook.
220
+ actor_task_id: Id of the Actor task whose runs should trigger the webhook.
221
+ actor_run_id: Id of the Actor run which should trigger the webhook.
222
+ ignore_ssl_errors: Whether the webhook should ignore SSL errors returned by request_url.
223
+ do_not_retry: Whether the webhook should retry sending the payload to request_url upon failure.
224
+ is_ad_hoc: Set to True if you want the webhook to be triggered only the first time the condition
225
+ is fulfilled. Only applicable when actor_run_id is filled.
226
+ timeout: Timeout for the API HTTP request.
227
+
228
+ Returns:
229
+ The updated webhook.
230
+ """
231
+ webhook_update = WebhookUpdate(
232
+ event_types=list(event_types) if event_types is not None else None,
233
+ request_url=AnyUrl(request_url) if request_url is not None else None,
234
+ payload_template=payload_template,
235
+ headers_template=headers_template,
236
+ ignore_ssl_errors=ignore_ssl_errors,
237
+ do_not_retry=do_not_retry,
238
+ is_ad_hoc=is_ad_hoc if actor_run_id else None,
239
+ condition=WebhookCondition(
240
+ actor_run_id=actor_run_id,
241
+ actor_task_id=actor_task_id,
242
+ actor_id=actor_id,
243
+ ),
244
+ )
245
+ result = await self._update(timeout=timeout, **webhook_update.model_dump(by_alias=True, exclude_none=True))
246
+ return WebhookResponse.model_validate(result).data
247
+
248
+ async def delete(self, *, timeout: Timeout = 'short') -> None:
249
+ """Delete the webhook.
250
+
251
+
252
+ Args:
253
+ timeout: Timeout for the API HTTP request.
254
+ """
255
+ await self._delete(timeout=timeout)
256
+
257
+ async def test(self, *, timeout: Timeout = 'medium') -> WebhookDispatch:
258
+ """Test a webhook.
259
+
260
+ Creates a webhook dispatch with a dummy payload.
261
+
262
+
263
+ Args:
264
+ timeout: Timeout for the API HTTP request.
265
+
266
+ Returns:
267
+ The webhook dispatch created by the test.
268
+
269
+ Raises:
270
+ NotFoundError: If the webhook does not exist.
271
+ """
272
+ response = await self._http_client.call(
273
+ url=self._build_url('test'),
274
+ method='POST',
275
+ params=self._build_params(),
276
+ timeout=timeout,
277
+ )
278
+
279
+ result = response_to_dict(response)
280
+ return TestWebhookResponse.model_validate(result).data
281
+
282
+ def dispatches(self) -> WebhookDispatchCollectionClientAsync:
283
+ """Get dispatches of the webhook.
284
+
285
+
286
+ Returns:
287
+ A client allowing access to dispatches of this webhook using its list method.
288
+ """
289
+ return self._client_registry.webhook_dispatch_collection_client(
290
+ resource_path='dispatches',
291
+ **self._base_client_kwargs,
292
+ )
@@ -0,0 +1,281 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from scrapely_client._docs import docs_group
6
+ from scrapely_client._models import (
7
+ ListOfWebhooks,
8
+ ListOfWebhooksResponse,
9
+ WebhookCondition,
10
+ WebhookCreate,
11
+ WebhookResponse,
12
+ )
13
+ from scrapely_client._pagination import get_items_iterator, get_items_iterator_async
14
+ from scrapely_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync
15
+
16
+ if TYPE_CHECKING:
17
+ from collections.abc import AsyncIterator, Iterator
18
+
19
+ from scrapely_client._literals import WebhookEventType
20
+ from scrapely_client._models import Webhook, WebhookShort
21
+ from scrapely_client.types import Timeout
22
+
23
+
24
+ @docs_group('Resource clients')
25
+ class WebhookCollectionClient(ResourceClient):
26
+ """Sub-client for the webhook collection.
27
+
28
+ Provides methods to manage the webhook collection, e.g. list or create webhooks. Obtain an instance via an
29
+ appropriate method on the `ApifyClient` class.
30
+ """
31
+
32
+ def __init__(
33
+ self,
34
+ *,
35
+ resource_path: str = 'webhooks',
36
+ **kwargs: Any,
37
+ ) -> None:
38
+ super().__init__(
39
+ resource_path=resource_path,
40
+ **kwargs,
41
+ )
42
+
43
+ def list(
44
+ self,
45
+ *,
46
+ limit: int | None = None,
47
+ offset: int | None = None,
48
+ desc: bool | None = None,
49
+ timeout: Timeout = 'medium',
50
+ ) -> ListOfWebhooks:
51
+ """List the available webhooks.
52
+
53
+
54
+ Args:
55
+ limit: How many webhooks to retrieve.
56
+ offset: What webhook to include as first when retrieving the list.
57
+ desc: Whether to sort the webhooks in descending order based on their date of creation.
58
+ timeout: Timeout for the API HTTP request.
59
+
60
+ Returns:
61
+ The list of available webhooks matching the specified filters.
62
+ """
63
+ result = self._list(timeout=timeout, limit=limit, offset=offset, desc=desc)
64
+ return ListOfWebhooksResponse.model_validate(result).data
65
+
66
+ def iterate(
67
+ self,
68
+ *,
69
+ limit: int | None = None,
70
+ offset: int | None = None,
71
+ desc: bool | None = None,
72
+ timeout: Timeout = 'medium',
73
+ ) -> Iterator[WebhookShort]:
74
+ """Iterate over the available webhooks.
75
+
76
+ Simple `list` does only one API call, possibly not listing all items matching the criteria. This method
77
+ returns an iterator that is capable of making multiple API calls to retrieve all items matching the criteria.
78
+
79
+
80
+ Args:
81
+ limit: How many webhooks to retrieve.
82
+ offset: What webhook to include as first when retrieving the list.
83
+ desc: Whether to sort the webhooks in descending order based on their date of creation.
84
+ timeout: Timeout for the API HTTP request.
85
+
86
+ Yields:
87
+ The available webhooks matching the specified filters.
88
+ """
89
+
90
+ def _callback(*, limit: int | None = None, offset: int | None = None) -> ListOfWebhooks:
91
+ return self.list(limit=limit, offset=offset, desc=desc, timeout=timeout)
92
+
93
+ return get_items_iterator(_callback, limit=limit, offset=offset)
94
+
95
+ def create(
96
+ self,
97
+ *,
98
+ event_types: list[WebhookEventType], # ty: ignore[invalid-type-form]
99
+ request_url: str,
100
+ payload_template: str | None = None,
101
+ headers_template: str | None = None,
102
+ actor_id: str | None = None,
103
+ actor_task_id: str | None = None,
104
+ actor_run_id: str | None = None,
105
+ ignore_ssl_errors: bool | None = None,
106
+ do_not_retry: bool | None = None,
107
+ idempotency_key: str | None = None,
108
+ is_ad_hoc: bool | None = None,
109
+ timeout: Timeout = 'short',
110
+ ) -> Webhook:
111
+ """Create a new webhook.
112
+
113
+ You have to specify exactly one out of actor_id, actor_task_id or actor_run_id.
114
+
115
+
116
+ Args:
117
+ event_types: List of event types that should trigger the webhook. At least one is required.
118
+ request_url: URL that will be invoked once the webhook is triggered.
119
+ payload_template: Specification of the payload that will be sent to request_url.
120
+ headers_template: Headers that will be sent to the request_url.
121
+ actor_id: Id of the Actor whose runs should trigger the webhook.
122
+ actor_task_id: Id of the Actor task whose runs should trigger the webhook.
123
+ actor_run_id: Id of the Actor run which should trigger the webhook.
124
+ ignore_ssl_errors: Whether the webhook should ignore SSL errors returned by request_url.
125
+ do_not_retry: Whether the webhook should retry sending the payload to request_url upon failure.
126
+ idempotency_key: A unique identifier of a webhook. You can use it to ensure that you won't create
127
+ the same webhook multiple times.
128
+ is_ad_hoc: Set to True if you want the webhook to be triggered only the first time the condition
129
+ is fulfilled. Only applicable when actor_run_id is filled.
130
+ timeout: Timeout for the API HTTP request.
131
+
132
+ Returns:
133
+ The created webhook.
134
+ """
135
+ webhook_create = WebhookCreate(
136
+ event_types=list(event_types),
137
+ request_url=request_url,
138
+ payload_template=payload_template,
139
+ headers_template=headers_template,
140
+ ignore_ssl_errors=ignore_ssl_errors,
141
+ do_not_retry=do_not_retry,
142
+ idempotency_key=idempotency_key,
143
+ is_ad_hoc=is_ad_hoc if actor_run_id else None,
144
+ condition=WebhookCondition(
145
+ actor_run_id=actor_run_id,
146
+ actor_task_id=actor_task_id,
147
+ actor_id=actor_id,
148
+ ),
149
+ )
150
+ result = self._create(timeout=timeout, **webhook_create.model_dump(by_alias=True, exclude_none=True))
151
+ return WebhookResponse.model_validate(result).data
152
+
153
+
154
+ @docs_group('Resource clients')
155
+ class WebhookCollectionClientAsync(ResourceClientAsync):
156
+ """Sub-client for the webhook collection.
157
+
158
+ Provides methods to manage the webhook collection, e.g. list or create webhooks. Obtain an instance via an
159
+ appropriate method on the `ApifyClientAsync` class.
160
+ """
161
+
162
+ def __init__(
163
+ self,
164
+ *,
165
+ resource_path: str = 'webhooks',
166
+ **kwargs: Any,
167
+ ) -> None:
168
+ super().__init__(
169
+ resource_path=resource_path,
170
+ **kwargs,
171
+ )
172
+
173
+ async def list(
174
+ self,
175
+ *,
176
+ limit: int | None = None,
177
+ offset: int | None = None,
178
+ desc: bool | None = None,
179
+ timeout: Timeout = 'medium',
180
+ ) -> ListOfWebhooks:
181
+ """List the available webhooks.
182
+
183
+
184
+ Args:
185
+ limit: How many webhooks to retrieve.
186
+ offset: What webhook to include as first when retrieving the list.
187
+ desc: Whether to sort the webhooks in descending order based on their date of creation.
188
+ timeout: Timeout for the API HTTP request.
189
+
190
+ Returns:
191
+ The list of available webhooks matching the specified filters.
192
+ """
193
+ result = await self._list(timeout=timeout, limit=limit, offset=offset, desc=desc)
194
+ return ListOfWebhooksResponse.model_validate(result).data
195
+
196
+ def iterate(
197
+ self,
198
+ *,
199
+ limit: int | None = None,
200
+ offset: int | None = None,
201
+ desc: bool | None = None,
202
+ timeout: Timeout = 'medium',
203
+ ) -> AsyncIterator[WebhookShort]:
204
+ """Iterate over the available webhooks.
205
+
206
+ Simple `list` does only one API call, possibly not listing all items matching the criteria. This method
207
+ returns an iterator that is capable of making multiple API calls to retrieve all items matching the criteria.
208
+
209
+
210
+ Args:
211
+ limit: How many webhooks to retrieve.
212
+ offset: What webhook to include as first when retrieving the list.
213
+ desc: Whether to sort the webhooks in descending order based on their date of creation.
214
+ timeout: Timeout for the API HTTP request.
215
+
216
+ Yields:
217
+ The available webhooks matching the specified filters.
218
+ """
219
+
220
+ async def _callback(*, limit: int | None = None, offset: int | None = None) -> ListOfWebhooks:
221
+ return await self.list(limit=limit, offset=offset, desc=desc, timeout=timeout)
222
+
223
+ return get_items_iterator_async(_callback, limit=limit, offset=offset)
224
+
225
+ async def create(
226
+ self,
227
+ *,
228
+ event_types: list[WebhookEventType], # ty: ignore[invalid-type-form]
229
+ request_url: str,
230
+ payload_template: str | None = None,
231
+ headers_template: str | None = None,
232
+ actor_id: str | None = None,
233
+ actor_task_id: str | None = None,
234
+ actor_run_id: str | None = None,
235
+ ignore_ssl_errors: bool | None = None,
236
+ do_not_retry: bool | None = None,
237
+ idempotency_key: str | None = None,
238
+ is_ad_hoc: bool | None = None,
239
+ timeout: Timeout = 'short',
240
+ ) -> Webhook:
241
+ """Create a new webhook.
242
+
243
+ You have to specify exactly one out of actor_id, actor_task_id or actor_run_id.
244
+
245
+
246
+ Args:
247
+ event_types: List of event types that should trigger the webhook. At least one is required.
248
+ request_url: URL that will be invoked once the webhook is triggered.
249
+ payload_template: Specification of the payload that will be sent to request_url.
250
+ headers_template: Headers that will be sent to the request_url.
251
+ actor_id: Id of the Actor whose runs should trigger the webhook.
252
+ actor_task_id: Id of the Actor task whose runs should trigger the webhook.
253
+ actor_run_id: Id of the Actor run which should trigger the webhook.
254
+ ignore_ssl_errors: Whether the webhook should ignore SSL errors returned by request_url.
255
+ do_not_retry: Whether the webhook should retry sending the payload to request_url upon failure.
256
+ idempotency_key: A unique identifier of a webhook. You can use it to ensure that you won't create
257
+ the same webhook multiple times.
258
+ is_ad_hoc: Set to True if you want the webhook to be triggered only the first time the condition
259
+ is fulfilled. Only applicable when actor_run_id is filled.
260
+ timeout: Timeout for the API HTTP request.
261
+
262
+ Returns:
263
+ The created webhook.
264
+ """
265
+ webhook_create = WebhookCreate(
266
+ event_types=list(event_types),
267
+ request_url=request_url,
268
+ payload_template=payload_template,
269
+ headers_template=headers_template,
270
+ ignore_ssl_errors=ignore_ssl_errors,
271
+ do_not_retry=do_not_retry,
272
+ idempotency_key=idempotency_key,
273
+ is_ad_hoc=is_ad_hoc if actor_run_id else None,
274
+ condition=WebhookCondition(
275
+ actor_run_id=actor_run_id,
276
+ actor_task_id=actor_task_id,
277
+ actor_id=actor_id,
278
+ ),
279
+ )
280
+ result = await self._create(timeout=timeout, **webhook_create.model_dump(by_alias=True, exclude_none=True))
281
+ return WebhookResponse.model_validate(result).data
@@ -0,0 +1,84 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from scrapely_client._docs import docs_group
6
+ from scrapely_client._models import WebhookDispatch, WebhookDispatchResponse
7
+ from scrapely_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync
8
+
9
+ if TYPE_CHECKING:
10
+ from scrapely_client.types import Timeout
11
+
12
+
13
+ @docs_group('Resource clients')
14
+ class WebhookDispatchClient(ResourceClient):
15
+ """Sub-client for managing a specific webhook dispatch.
16
+
17
+ Provides methods to manage a specific webhook dispatch, e.g. get its details. Obtain an instance via an appropriate
18
+ method on the `ApifyClient` class.
19
+ """
20
+
21
+ def __init__(
22
+ self,
23
+ *,
24
+ resource_id: str,
25
+ resource_path: str = 'webhook-dispatches',
26
+ **kwargs: Any,
27
+ ) -> None:
28
+ super().__init__(
29
+ resource_id=resource_id,
30
+ resource_path=resource_path,
31
+ **kwargs,
32
+ )
33
+
34
+ def get(self, *, timeout: Timeout = 'short') -> WebhookDispatch | None:
35
+ """Retrieve the webhook dispatch.
36
+
37
+
38
+ Args:
39
+ timeout: Timeout for the API HTTP request.
40
+
41
+ Returns:
42
+ The retrieved webhook dispatch, or None if it does not exist.
43
+ """
44
+ result = self._get(timeout=timeout)
45
+ if result is None:
46
+ return None
47
+ return WebhookDispatchResponse.model_validate(result).data
48
+
49
+
50
+ @docs_group('Resource clients')
51
+ class WebhookDispatchClientAsync(ResourceClientAsync):
52
+ """Sub-client for managing a specific webhook dispatch.
53
+
54
+ Provides methods to manage a specific webhook dispatch, e.g. get its details. Obtain an instance via an appropriate
55
+ method on the `ApifyClientAsync` class.
56
+ """
57
+
58
+ def __init__(
59
+ self,
60
+ *,
61
+ resource_id: str,
62
+ resource_path: str = 'webhook-dispatches',
63
+ **kwargs: Any,
64
+ ) -> None:
65
+ super().__init__(
66
+ resource_id=resource_id,
67
+ resource_path=resource_path,
68
+ **kwargs,
69
+ )
70
+
71
+ async def get(self, *, timeout: Timeout = 'short') -> WebhookDispatch | None:
72
+ """Retrieve the webhook dispatch.
73
+
74
+
75
+ Args:
76
+ timeout: Timeout for the API HTTP request.
77
+
78
+ Returns:
79
+ The retrieved webhook dispatch, or None if it does not exist.
80
+ """
81
+ result = await self._get(timeout=timeout)
82
+ if result is None:
83
+ return None
84
+ return WebhookDispatchResponse.model_validate(result).data