airweave-sdk 0.8.65__py3-none-any.whl → 0.8.66__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.
- airweave/__init__.py +41 -43
- airweave/client.py +0 -16
- airweave/collections/__init__.py +3 -6
- airweave/collections/client.py +273 -113
- airweave/collections/raw_client.py +633 -94
- airweave/collections/types/__init__.py +2 -4
- airweave/core/client_wrapper.py +4 -30
- airweave/errors/__init__.py +10 -2
- airweave/errors/conflict_error.py +11 -0
- airweave/errors/not_found_error.py +11 -0
- airweave/errors/too_many_requests_error.py +11 -0
- airweave/errors/unprocessable_entity_error.py +1 -2
- airweave/events/client.py +281 -500
- airweave/events/raw_client.py +562 -551
- airweave/source_connections/client.py +210 -162
- airweave/source_connections/raw_client.py +574 -137
- airweave/sources/client.py +42 -18
- airweave/sources/raw_client.py +118 -17
- airweave/types/__init__.py +33 -39
- airweave/types/{endpoint_secret_out.py → conflict_error_response.py} +12 -2
- airweave/types/delivery_attempt.py +61 -0
- airweave/types/event_message.py +55 -0
- airweave/types/event_message_with_attempts.py +59 -0
- airweave/types/{enable_endpoint_request.py → not_found_error_response.py} +6 -4
- airweave/types/{subscription_with_attempts_out.py → rate_limit_error_response.py} +9 -6
- airweave/types/recovery_task.py +35 -0
- airweave/types/search_request.py +13 -10
- airweave/types/search_response.py +6 -3
- airweave/types/source_connection.py +73 -18
- airweave/types/source_connection_job.py +65 -15
- airweave/types/source_connection_list_item.py +45 -10
- airweave/types/sync_event_payload.py +72 -0
- airweave/types/{recover_out.py → validation_error_detail.py} +19 -6
- airweave/types/validation_error_response.py +30 -0
- airweave/types/webhook_subscription.py +68 -0
- {airweave_sdk-0.8.65.dist-info → airweave_sdk-0.8.66.dist-info}/METADATA +1 -5
- {airweave_sdk-0.8.65.dist-info → airweave_sdk-0.8.66.dist-info}/RECORD +38 -38
- airweave/collections/types/search_collections_readable_id_search_post_response.py +0 -8
- airweave/types/background_task_status.py +0 -5
- airweave/types/background_task_type.py +0 -17
- airweave/types/collection_update.py +0 -35
- airweave/types/endpoint_out.py +0 -35
- airweave/types/message_attempt_out.py +0 -37
- airweave/types/message_attempt_trigger_type.py +0 -3
- airweave/types/message_out.py +0 -29
- airweave/types/message_status.py +0 -3
- airweave/types/message_status_text.py +0 -5
- {airweave_sdk-0.8.65.dist-info → airweave_sdk-0.8.66.dist-info}/WHEEL +0 -0
airweave/events/raw_client.py
CHANGED
|
@@ -10,17 +10,16 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse
|
|
|
10
10
|
from ..core.jsonable_encoder import jsonable_encoder
|
|
11
11
|
from ..core.pydantic_utilities import parse_obj_as
|
|
12
12
|
from ..core.request_options import RequestOptions
|
|
13
|
-
from ..
|
|
13
|
+
from ..errors.not_found_error import NotFoundError
|
|
14
|
+
from ..errors.too_many_requests_error import TooManyRequestsError
|
|
14
15
|
from ..errors.unprocessable_entity_error import UnprocessableEntityError
|
|
15
|
-
from ..types.
|
|
16
|
-
from ..types.
|
|
17
|
-
from ..types.endpoint_secret_out import EndpointSecretOut
|
|
16
|
+
from ..types.event_message import EventMessage
|
|
17
|
+
from ..types.event_message_with_attempts import EventMessageWithAttempts
|
|
18
18
|
from ..types.event_type import EventType
|
|
19
|
-
from ..types.
|
|
20
|
-
from ..types.
|
|
21
|
-
from ..types.
|
|
22
|
-
from ..types.
|
|
23
|
-
from ..types.subscription_with_attempts_out import SubscriptionWithAttemptsOut
|
|
19
|
+
from ..types.not_found_error_response import NotFoundErrorResponse
|
|
20
|
+
from ..types.rate_limit_error_response import RateLimitErrorResponse
|
|
21
|
+
from ..types.recovery_task import RecoveryTask
|
|
22
|
+
from ..types.webhook_subscription import WebhookSubscription
|
|
24
23
|
|
|
25
24
|
# this is used as the default value for optional parameters
|
|
26
25
|
OMIT = typing.cast(typing.Any, ...)
|
|
@@ -35,28 +34,29 @@ class RawEventsClient:
|
|
|
35
34
|
*,
|
|
36
35
|
event_types: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
|
|
37
36
|
request_options: typing.Optional[RequestOptions] = None,
|
|
38
|
-
) -> HttpResponse[typing.List[
|
|
37
|
+
) -> HttpResponse[typing.List[EventMessage]]:
|
|
39
38
|
"""
|
|
40
|
-
|
|
39
|
+
Retrieve all event messages for your organization.
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
Event messages represent webhook payloads that were sent (or attempted to be sent)
|
|
42
|
+
to your subscribed endpoints. Each message contains the event type, payload data,
|
|
43
|
+
and delivery status information.
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
Use the `event_types` query parameter to filter messages by specific event types,
|
|
46
|
+
such as `sync.completed` or `sync.failed`.
|
|
48
47
|
|
|
49
48
|
Parameters
|
|
50
49
|
----------
|
|
51
50
|
event_types : typing.Optional[typing.Union[str, typing.Sequence[str]]]
|
|
51
|
+
Filter messages by event type(s). Accepts multiple values, e.g., `?event_types=sync.completed&event_types=sync.failed`.
|
|
52
52
|
|
|
53
53
|
request_options : typing.Optional[RequestOptions]
|
|
54
54
|
Request-specific configuration.
|
|
55
55
|
|
|
56
56
|
Returns
|
|
57
57
|
-------
|
|
58
|
-
HttpResponse[typing.List[
|
|
59
|
-
|
|
58
|
+
HttpResponse[typing.List[EventMessage]]
|
|
59
|
+
List of event messages
|
|
60
60
|
"""
|
|
61
61
|
_response = self._client_wrapper.httpx_client.request(
|
|
62
62
|
"events/messages",
|
|
@@ -69,9 +69,9 @@ class RawEventsClient:
|
|
|
69
69
|
try:
|
|
70
70
|
if 200 <= _response.status_code < 300:
|
|
71
71
|
_data = typing.cast(
|
|
72
|
-
typing.List[
|
|
72
|
+
typing.List[EventMessage],
|
|
73
73
|
parse_obj_as(
|
|
74
|
-
type_=typing.List[
|
|
74
|
+
type_=typing.List[EventMessage], # type: ignore
|
|
75
75
|
object_=_response.json(),
|
|
76
76
|
),
|
|
77
77
|
)
|
|
@@ -80,9 +80,20 @@ class RawEventsClient:
|
|
|
80
80
|
raise UnprocessableEntityError(
|
|
81
81
|
headers=dict(_response.headers),
|
|
82
82
|
body=typing.cast(
|
|
83
|
-
|
|
83
|
+
typing.Optional[typing.Any],
|
|
84
84
|
parse_obj_as(
|
|
85
|
-
type_=
|
|
85
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
86
|
+
object_=_response.json(),
|
|
87
|
+
),
|
|
88
|
+
),
|
|
89
|
+
)
|
|
90
|
+
if _response.status_code == 429:
|
|
91
|
+
raise TooManyRequestsError(
|
|
92
|
+
headers=dict(_response.headers),
|
|
93
|
+
body=typing.cast(
|
|
94
|
+
RateLimitErrorResponse,
|
|
95
|
+
parse_obj_as(
|
|
96
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
86
97
|
object_=_response.json(),
|
|
87
98
|
),
|
|
88
99
|
),
|
|
@@ -93,108 +104,86 @@ class RawEventsClient:
|
|
|
93
104
|
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
94
105
|
|
|
95
106
|
def get_message(
|
|
96
|
-
self,
|
|
97
|
-
|
|
107
|
+
self,
|
|
108
|
+
message_id: str,
|
|
109
|
+
*,
|
|
110
|
+
include_attempts: typing.Optional[bool] = None,
|
|
111
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
112
|
+
) -> HttpResponse[EventMessageWithAttempts]:
|
|
98
113
|
"""
|
|
99
|
-
|
|
114
|
+
Retrieve a specific event message by its ID.
|
|
100
115
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
116
|
+
Returns the full message details including the event type, payload data,
|
|
117
|
+
timestamp, and delivery channel information. Use this to inspect the
|
|
118
|
+
exact payload that was sent to your webhook endpoints.
|
|
104
119
|
|
|
105
|
-
|
|
106
|
-
|
|
120
|
+
Use `include_attempts=true` to also retrieve delivery attempts for this message,
|
|
121
|
+
which include HTTP response codes, response bodies, and timestamps for debugging
|
|
122
|
+
delivery failures.
|
|
107
123
|
|
|
108
124
|
Parameters
|
|
109
125
|
----------
|
|
110
126
|
message_id : str
|
|
127
|
+
The unique identifier of the message to retrieve (UUID).
|
|
128
|
+
|
|
129
|
+
include_attempts : typing.Optional[bool]
|
|
130
|
+
Include delivery attempts for this message. Each attempt includes the HTTP response code, response body, and timestamp.
|
|
111
131
|
|
|
112
132
|
request_options : typing.Optional[RequestOptions]
|
|
113
133
|
Request-specific configuration.
|
|
114
134
|
|
|
115
135
|
Returns
|
|
116
136
|
-------
|
|
117
|
-
HttpResponse[
|
|
118
|
-
|
|
137
|
+
HttpResponse[EventMessageWithAttempts]
|
|
138
|
+
Event message details
|
|
119
139
|
"""
|
|
120
140
|
_response = self._client_wrapper.httpx_client.request(
|
|
121
141
|
f"events/messages/{jsonable_encoder(message_id)}",
|
|
122
142
|
method="GET",
|
|
143
|
+
params={
|
|
144
|
+
"include_attempts": include_attempts,
|
|
145
|
+
},
|
|
123
146
|
request_options=request_options,
|
|
124
147
|
)
|
|
125
148
|
try:
|
|
126
149
|
if 200 <= _response.status_code < 300:
|
|
127
150
|
_data = typing.cast(
|
|
128
|
-
|
|
151
|
+
EventMessageWithAttempts,
|
|
129
152
|
parse_obj_as(
|
|
130
|
-
type_=
|
|
153
|
+
type_=EventMessageWithAttempts, # type: ignore
|
|
131
154
|
object_=_response.json(),
|
|
132
155
|
),
|
|
133
156
|
)
|
|
134
157
|
return HttpResponse(response=_response, data=_data)
|
|
135
|
-
if _response.status_code ==
|
|
136
|
-
raise
|
|
158
|
+
if _response.status_code == 404:
|
|
159
|
+
raise NotFoundError(
|
|
137
160
|
headers=dict(_response.headers),
|
|
138
161
|
body=typing.cast(
|
|
139
|
-
|
|
162
|
+
NotFoundErrorResponse,
|
|
140
163
|
parse_obj_as(
|
|
141
|
-
type_=
|
|
164
|
+
type_=NotFoundErrorResponse, # type: ignore
|
|
142
165
|
object_=_response.json(),
|
|
143
166
|
),
|
|
144
167
|
),
|
|
145
168
|
)
|
|
146
|
-
_response_json = _response.json()
|
|
147
|
-
except JSONDecodeError:
|
|
148
|
-
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
149
|
-
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
150
|
-
|
|
151
|
-
def get_message_attempts(
|
|
152
|
-
self, message_id: str, *, request_options: typing.Optional[RequestOptions] = None
|
|
153
|
-
) -> HttpResponse[typing.List[MessageAttemptOut]]:
|
|
154
|
-
"""
|
|
155
|
-
Get delivery attempts for a specific message.
|
|
156
|
-
|
|
157
|
-
Args:
|
|
158
|
-
message_id: The ID of the message.
|
|
159
|
-
ctx: The API context containing organization info.
|
|
160
|
-
|
|
161
|
-
Returns:
|
|
162
|
-
List of delivery attempts for this message.
|
|
163
|
-
|
|
164
|
-
Parameters
|
|
165
|
-
----------
|
|
166
|
-
message_id : str
|
|
167
|
-
|
|
168
|
-
request_options : typing.Optional[RequestOptions]
|
|
169
|
-
Request-specific configuration.
|
|
170
|
-
|
|
171
|
-
Returns
|
|
172
|
-
-------
|
|
173
|
-
HttpResponse[typing.List[MessageAttemptOut]]
|
|
174
|
-
Successful Response
|
|
175
|
-
"""
|
|
176
|
-
_response = self._client_wrapper.httpx_client.request(
|
|
177
|
-
f"events/messages/{jsonable_encoder(message_id)}/attempts",
|
|
178
|
-
method="GET",
|
|
179
|
-
request_options=request_options,
|
|
180
|
-
)
|
|
181
|
-
try:
|
|
182
|
-
if 200 <= _response.status_code < 300:
|
|
183
|
-
_data = typing.cast(
|
|
184
|
-
typing.List[MessageAttemptOut],
|
|
185
|
-
parse_obj_as(
|
|
186
|
-
type_=typing.List[MessageAttemptOut], # type: ignore
|
|
187
|
-
object_=_response.json(),
|
|
188
|
-
),
|
|
189
|
-
)
|
|
190
|
-
return HttpResponse(response=_response, data=_data)
|
|
191
169
|
if _response.status_code == 422:
|
|
192
170
|
raise UnprocessableEntityError(
|
|
193
171
|
headers=dict(_response.headers),
|
|
194
172
|
body=typing.cast(
|
|
195
|
-
|
|
173
|
+
typing.Optional[typing.Any],
|
|
174
|
+
parse_obj_as(
|
|
175
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
176
|
+
object_=_response.json(),
|
|
177
|
+
),
|
|
178
|
+
),
|
|
179
|
+
)
|
|
180
|
+
if _response.status_code == 429:
|
|
181
|
+
raise TooManyRequestsError(
|
|
182
|
+
headers=dict(_response.headers),
|
|
183
|
+
body=typing.cast(
|
|
184
|
+
RateLimitErrorResponse,
|
|
196
185
|
parse_obj_as(
|
|
197
|
-
type_=
|
|
186
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
198
187
|
object_=_response.json(),
|
|
199
188
|
),
|
|
200
189
|
),
|
|
@@ -206,15 +195,13 @@ class RawEventsClient:
|
|
|
206
195
|
|
|
207
196
|
def get_subscriptions(
|
|
208
197
|
self, *, request_options: typing.Optional[RequestOptions] = None
|
|
209
|
-
) -> HttpResponse[typing.List[
|
|
198
|
+
) -> HttpResponse[typing.List[WebhookSubscription]]:
|
|
210
199
|
"""
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
Args:
|
|
214
|
-
ctx: The API context containing organization info.
|
|
200
|
+
List all webhook subscriptions for your organization.
|
|
215
201
|
|
|
216
|
-
Returns
|
|
217
|
-
|
|
202
|
+
Returns all configured webhook endpoints, including their URLs, subscribed
|
|
203
|
+
event types, and current status (enabled/disabled). Use this to audit
|
|
204
|
+
your webhook configuration or find a specific subscription.
|
|
218
205
|
|
|
219
206
|
Parameters
|
|
220
207
|
----------
|
|
@@ -223,8 +210,8 @@ class RawEventsClient:
|
|
|
223
210
|
|
|
224
211
|
Returns
|
|
225
212
|
-------
|
|
226
|
-
HttpResponse[typing.List[
|
|
227
|
-
|
|
213
|
+
HttpResponse[typing.List[WebhookSubscription]]
|
|
214
|
+
List of webhook subscriptions
|
|
228
215
|
"""
|
|
229
216
|
_response = self._client_wrapper.httpx_client.request(
|
|
230
217
|
"events/subscriptions",
|
|
@@ -234,9 +221,9 @@ class RawEventsClient:
|
|
|
234
221
|
try:
|
|
235
222
|
if 200 <= _response.status_code < 300:
|
|
236
223
|
_data = typing.cast(
|
|
237
|
-
typing.List[
|
|
224
|
+
typing.List[WebhookSubscription],
|
|
238
225
|
parse_obj_as(
|
|
239
|
-
type_=typing.List[
|
|
226
|
+
type_=typing.List[WebhookSubscription], # type: ignore
|
|
240
227
|
object_=_response.json(),
|
|
241
228
|
),
|
|
242
229
|
)
|
|
@@ -245,9 +232,20 @@ class RawEventsClient:
|
|
|
245
232
|
raise UnprocessableEntityError(
|
|
246
233
|
headers=dict(_response.headers),
|
|
247
234
|
body=typing.cast(
|
|
248
|
-
|
|
235
|
+
typing.Optional[typing.Any],
|
|
249
236
|
parse_obj_as(
|
|
250
|
-
type_=
|
|
237
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
238
|
+
object_=_response.json(),
|
|
239
|
+
),
|
|
240
|
+
),
|
|
241
|
+
)
|
|
242
|
+
if _response.status_code == 429:
|
|
243
|
+
raise TooManyRequestsError(
|
|
244
|
+
headers=dict(_response.headers),
|
|
245
|
+
body=typing.cast(
|
|
246
|
+
RateLimitErrorResponse,
|
|
247
|
+
parse_obj_as(
|
|
248
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
251
249
|
object_=_response.json(),
|
|
252
250
|
),
|
|
253
251
|
),
|
|
@@ -264,32 +262,38 @@ class RawEventsClient:
|
|
|
264
262
|
event_types: typing.Sequence[EventType],
|
|
265
263
|
secret: typing.Optional[str] = OMIT,
|
|
266
264
|
request_options: typing.Optional[RequestOptions] = None,
|
|
267
|
-
) -> HttpResponse[
|
|
265
|
+
) -> HttpResponse[WebhookSubscription]:
|
|
268
266
|
"""
|
|
269
267
|
Create a new webhook subscription.
|
|
270
268
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
269
|
+
Webhook subscriptions allow you to receive real-time notifications when events
|
|
270
|
+
occur in Airweave. When you create a subscription, you specify:
|
|
271
|
+
|
|
272
|
+
- **URL**: The HTTPS endpoint where events will be delivered
|
|
273
|
+
- **Event Types**: Which events you want to receive (e.g., `sync.completed`, `sync.failed`)
|
|
274
|
+
- **Secret** (optional): A custom signing secret for verifying webhook signatures
|
|
274
275
|
|
|
275
|
-
|
|
276
|
-
|
|
276
|
+
After creation, Airweave will send HTTP POST requests to your URL whenever
|
|
277
|
+
matching events occur. Each request includes a signature header for verification.
|
|
277
278
|
|
|
278
279
|
Parameters
|
|
279
280
|
----------
|
|
280
281
|
url : str
|
|
282
|
+
The HTTPS URL where webhook events will be delivered. Must be a publicly accessible endpoint that returns a 2xx status code.
|
|
281
283
|
|
|
282
284
|
event_types : typing.Sequence[EventType]
|
|
285
|
+
List of event types to subscribe to. Events not in this list will not be delivered to this subscription. Available types: `sync.pending`, `sync.running`, `sync.completed`, `sync.failed`, `sync.cancelled`.
|
|
283
286
|
|
|
284
287
|
secret : typing.Optional[str]
|
|
288
|
+
Optional custom signing secret for webhook signature verification. If not provided, a secure secret will be auto-generated. Must be at least 24 characters if specified.
|
|
285
289
|
|
|
286
290
|
request_options : typing.Optional[RequestOptions]
|
|
287
291
|
Request-specific configuration.
|
|
288
292
|
|
|
289
293
|
Returns
|
|
290
294
|
-------
|
|
291
|
-
HttpResponse[
|
|
292
|
-
|
|
295
|
+
HttpResponse[WebhookSubscription]
|
|
296
|
+
Created subscription
|
|
293
297
|
"""
|
|
294
298
|
_response = self._client_wrapper.httpx_client.request(
|
|
295
299
|
"events/subscriptions",
|
|
@@ -308,9 +312,9 @@ class RawEventsClient:
|
|
|
308
312
|
try:
|
|
309
313
|
if 200 <= _response.status_code < 300:
|
|
310
314
|
_data = typing.cast(
|
|
311
|
-
|
|
315
|
+
WebhookSubscription,
|
|
312
316
|
parse_obj_as(
|
|
313
|
-
type_=
|
|
317
|
+
type_=WebhookSubscription, # type: ignore
|
|
314
318
|
object_=_response.json(),
|
|
315
319
|
),
|
|
316
320
|
)
|
|
@@ -319,9 +323,20 @@ class RawEventsClient:
|
|
|
319
323
|
raise UnprocessableEntityError(
|
|
320
324
|
headers=dict(_response.headers),
|
|
321
325
|
body=typing.cast(
|
|
322
|
-
|
|
326
|
+
typing.Optional[typing.Any],
|
|
323
327
|
parse_obj_as(
|
|
324
|
-
type_=
|
|
328
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
329
|
+
object_=_response.json(),
|
|
330
|
+
),
|
|
331
|
+
),
|
|
332
|
+
)
|
|
333
|
+
if _response.status_code == 429:
|
|
334
|
+
raise TooManyRequestsError(
|
|
335
|
+
headers=dict(_response.headers),
|
|
336
|
+
body=typing.cast(
|
|
337
|
+
RateLimitErrorResponse,
|
|
338
|
+
parse_obj_as(
|
|
339
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
325
340
|
object_=_response.json(),
|
|
326
341
|
),
|
|
327
342
|
),
|
|
@@ -332,52 +347,85 @@ class RawEventsClient:
|
|
|
332
347
|
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
333
348
|
|
|
334
349
|
def get_subscription(
|
|
335
|
-
self,
|
|
336
|
-
|
|
350
|
+
self,
|
|
351
|
+
subscription_id: str,
|
|
352
|
+
*,
|
|
353
|
+
include_secret: typing.Optional[bool] = None,
|
|
354
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
355
|
+
) -> HttpResponse[WebhookSubscription]:
|
|
337
356
|
"""
|
|
338
|
-
|
|
357
|
+
Retrieve a specific webhook subscription with its recent delivery attempts.
|
|
339
358
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
359
|
+
Returns the subscription configuration along with a history of message delivery
|
|
360
|
+
attempts. This is useful for debugging delivery issues or verifying that your
|
|
361
|
+
endpoint is correctly receiving events.
|
|
343
362
|
|
|
344
|
-
|
|
345
|
-
|
|
363
|
+
Use `include_secret=true` to also retrieve the signing secret for webhook
|
|
364
|
+
signature verification. Keep this secret secure.
|
|
346
365
|
|
|
347
366
|
Parameters
|
|
348
367
|
----------
|
|
349
368
|
subscription_id : str
|
|
369
|
+
The unique identifier of the subscription to retrieve (UUID).
|
|
370
|
+
|
|
371
|
+
include_secret : typing.Optional[bool]
|
|
372
|
+
Include the signing secret for webhook signature verification. Keep this secret secure and use it to verify the 'svix-signature' header.
|
|
350
373
|
|
|
351
374
|
request_options : typing.Optional[RequestOptions]
|
|
352
375
|
Request-specific configuration.
|
|
353
376
|
|
|
354
377
|
Returns
|
|
355
378
|
-------
|
|
356
|
-
HttpResponse[
|
|
357
|
-
|
|
379
|
+
HttpResponse[WebhookSubscription]
|
|
380
|
+
Subscription with delivery attempts
|
|
358
381
|
"""
|
|
359
382
|
_response = self._client_wrapper.httpx_client.request(
|
|
360
383
|
f"events/subscriptions/{jsonable_encoder(subscription_id)}",
|
|
361
384
|
method="GET",
|
|
385
|
+
params={
|
|
386
|
+
"include_secret": include_secret,
|
|
387
|
+
},
|
|
362
388
|
request_options=request_options,
|
|
363
389
|
)
|
|
364
390
|
try:
|
|
365
391
|
if 200 <= _response.status_code < 300:
|
|
366
392
|
_data = typing.cast(
|
|
367
|
-
|
|
393
|
+
WebhookSubscription,
|
|
368
394
|
parse_obj_as(
|
|
369
|
-
type_=
|
|
395
|
+
type_=WebhookSubscription, # type: ignore
|
|
370
396
|
object_=_response.json(),
|
|
371
397
|
),
|
|
372
398
|
)
|
|
373
399
|
return HttpResponse(response=_response, data=_data)
|
|
400
|
+
if _response.status_code == 404:
|
|
401
|
+
raise NotFoundError(
|
|
402
|
+
headers=dict(_response.headers),
|
|
403
|
+
body=typing.cast(
|
|
404
|
+
NotFoundErrorResponse,
|
|
405
|
+
parse_obj_as(
|
|
406
|
+
type_=NotFoundErrorResponse, # type: ignore
|
|
407
|
+
object_=_response.json(),
|
|
408
|
+
),
|
|
409
|
+
),
|
|
410
|
+
)
|
|
374
411
|
if _response.status_code == 422:
|
|
375
412
|
raise UnprocessableEntityError(
|
|
376
413
|
headers=dict(_response.headers),
|
|
377
414
|
body=typing.cast(
|
|
378
|
-
|
|
415
|
+
typing.Optional[typing.Any],
|
|
379
416
|
parse_obj_as(
|
|
380
|
-
type_=
|
|
417
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
418
|
+
object_=_response.json(),
|
|
419
|
+
),
|
|
420
|
+
),
|
|
421
|
+
)
|
|
422
|
+
if _response.status_code == 429:
|
|
423
|
+
raise TooManyRequestsError(
|
|
424
|
+
headers=dict(_response.headers),
|
|
425
|
+
body=typing.cast(
|
|
426
|
+
RateLimitErrorResponse,
|
|
427
|
+
parse_obj_as(
|
|
428
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
381
429
|
object_=_response.json(),
|
|
382
430
|
),
|
|
383
431
|
),
|
|
@@ -389,25 +437,28 @@ class RawEventsClient:
|
|
|
389
437
|
|
|
390
438
|
def delete_subscription(
|
|
391
439
|
self, subscription_id: str, *, request_options: typing.Optional[RequestOptions] = None
|
|
392
|
-
) -> HttpResponse[
|
|
440
|
+
) -> HttpResponse[WebhookSubscription]:
|
|
393
441
|
"""
|
|
394
|
-
|
|
442
|
+
Permanently delete a webhook subscription.
|
|
395
443
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
444
|
+
Once deleted, Airweave will stop sending events to this endpoint immediately.
|
|
445
|
+
This action cannot be undone. Any pending message deliveries will be cancelled.
|
|
446
|
+
|
|
447
|
+
If you want to temporarily stop receiving events, consider disabling the
|
|
448
|
+
subscription instead using the PATCH endpoint.
|
|
399
449
|
|
|
400
450
|
Parameters
|
|
401
451
|
----------
|
|
402
452
|
subscription_id : str
|
|
453
|
+
The unique identifier of the subscription to delete (UUID).
|
|
403
454
|
|
|
404
455
|
request_options : typing.Optional[RequestOptions]
|
|
405
456
|
Request-specific configuration.
|
|
406
457
|
|
|
407
458
|
Returns
|
|
408
459
|
-------
|
|
409
|
-
HttpResponse[
|
|
410
|
-
|
|
460
|
+
HttpResponse[WebhookSubscription]
|
|
461
|
+
Deleted subscription
|
|
411
462
|
"""
|
|
412
463
|
_response = self._client_wrapper.httpx_client.request(
|
|
413
464
|
f"events/subscriptions/{jsonable_encoder(subscription_id)}",
|
|
@@ -415,24 +466,44 @@ class RawEventsClient:
|
|
|
415
466
|
request_options=request_options,
|
|
416
467
|
)
|
|
417
468
|
try:
|
|
418
|
-
if _response is None or not _response.text.strip():
|
|
419
|
-
return HttpResponse(response=_response, data=None)
|
|
420
469
|
if 200 <= _response.status_code < 300:
|
|
421
470
|
_data = typing.cast(
|
|
422
|
-
|
|
471
|
+
WebhookSubscription,
|
|
423
472
|
parse_obj_as(
|
|
424
|
-
type_=
|
|
473
|
+
type_=WebhookSubscription, # type: ignore
|
|
425
474
|
object_=_response.json(),
|
|
426
475
|
),
|
|
427
476
|
)
|
|
428
477
|
return HttpResponse(response=_response, data=_data)
|
|
478
|
+
if _response.status_code == 404:
|
|
479
|
+
raise NotFoundError(
|
|
480
|
+
headers=dict(_response.headers),
|
|
481
|
+
body=typing.cast(
|
|
482
|
+
NotFoundErrorResponse,
|
|
483
|
+
parse_obj_as(
|
|
484
|
+
type_=NotFoundErrorResponse, # type: ignore
|
|
485
|
+
object_=_response.json(),
|
|
486
|
+
),
|
|
487
|
+
),
|
|
488
|
+
)
|
|
429
489
|
if _response.status_code == 422:
|
|
430
490
|
raise UnprocessableEntityError(
|
|
431
491
|
headers=dict(_response.headers),
|
|
432
492
|
body=typing.cast(
|
|
433
|
-
|
|
493
|
+
typing.Optional[typing.Any],
|
|
434
494
|
parse_obj_as(
|
|
435
|
-
type_=
|
|
495
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
496
|
+
object_=_response.json(),
|
|
497
|
+
),
|
|
498
|
+
),
|
|
499
|
+
)
|
|
500
|
+
if _response.status_code == 429:
|
|
501
|
+
raise TooManyRequestsError(
|
|
502
|
+
headers=dict(_response.headers),
|
|
503
|
+
body=typing.cast(
|
|
504
|
+
RateLimitErrorResponse,
|
|
505
|
+
parse_obj_as(
|
|
506
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
436
507
|
object_=_response.json(),
|
|
437
508
|
),
|
|
438
509
|
),
|
|
@@ -449,36 +520,50 @@ class RawEventsClient:
|
|
|
449
520
|
url: typing.Optional[str] = OMIT,
|
|
450
521
|
event_types: typing.Optional[typing.Sequence[EventType]] = OMIT,
|
|
451
522
|
disabled: typing.Optional[bool] = OMIT,
|
|
523
|
+
recover_since: typing.Optional[dt.datetime] = OMIT,
|
|
452
524
|
request_options: typing.Optional[RequestOptions] = None,
|
|
453
|
-
) -> HttpResponse[
|
|
525
|
+
) -> HttpResponse[WebhookSubscription]:
|
|
454
526
|
"""
|
|
455
|
-
Update
|
|
527
|
+
Update an existing webhook subscription.
|
|
528
|
+
|
|
529
|
+
Use this endpoint to modify a subscription's configuration. You can:
|
|
456
530
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
531
|
+
- **Change the URL**: Update where events are delivered
|
|
532
|
+
- **Update event types**: Modify which events trigger notifications
|
|
533
|
+
- **Enable/disable**: Temporarily pause delivery without deleting the subscription
|
|
534
|
+
- **Recover messages**: When re-enabling, optionally recover missed messages
|
|
461
535
|
|
|
462
|
-
|
|
463
|
-
|
|
536
|
+
Only include the fields you want to change. Omitted fields will retain their
|
|
537
|
+
current values.
|
|
538
|
+
|
|
539
|
+
When re-enabling a subscription (`disabled: false`), you can optionally provide
|
|
540
|
+
`recover_since` to automatically retry all messages that were generated while
|
|
541
|
+
the subscription was disabled.
|
|
464
542
|
|
|
465
543
|
Parameters
|
|
466
544
|
----------
|
|
467
545
|
subscription_id : str
|
|
546
|
+
The unique identifier of the subscription to update (UUID).
|
|
468
547
|
|
|
469
548
|
url : typing.Optional[str]
|
|
549
|
+
New URL for webhook delivery. Must be a publicly accessible HTTPS endpoint.
|
|
470
550
|
|
|
471
551
|
event_types : typing.Optional[typing.Sequence[EventType]]
|
|
552
|
+
New list of event types to subscribe to. This replaces the existing list entirely.
|
|
472
553
|
|
|
473
554
|
disabled : typing.Optional[bool]
|
|
555
|
+
Set to `true` to pause delivery to this subscription, or `false` to resume. Disabled subscriptions will not receive events.
|
|
556
|
+
|
|
557
|
+
recover_since : typing.Optional[dt.datetime]
|
|
558
|
+
When re-enabling a subscription (`disabled: false`), optionally recover failed messages from this timestamp. Only applies when enabling.
|
|
474
559
|
|
|
475
560
|
request_options : typing.Optional[RequestOptions]
|
|
476
561
|
Request-specific configuration.
|
|
477
562
|
|
|
478
563
|
Returns
|
|
479
564
|
-------
|
|
480
|
-
HttpResponse[
|
|
481
|
-
|
|
565
|
+
HttpResponse[WebhookSubscription]
|
|
566
|
+
Updated subscription
|
|
482
567
|
"""
|
|
483
568
|
_response = self._client_wrapper.httpx_client.request(
|
|
484
569
|
f"events/subscriptions/{jsonable_encoder(subscription_id)}",
|
|
@@ -487,6 +572,7 @@ class RawEventsClient:
|
|
|
487
572
|
"url": url,
|
|
488
573
|
"event_types": event_types,
|
|
489
574
|
"disabled": disabled,
|
|
575
|
+
"recover_since": recover_since,
|
|
490
576
|
},
|
|
491
577
|
headers={
|
|
492
578
|
"content-type": "application/json",
|
|
@@ -497,146 +583,42 @@ class RawEventsClient:
|
|
|
497
583
|
try:
|
|
498
584
|
if 200 <= _response.status_code < 300:
|
|
499
585
|
_data = typing.cast(
|
|
500
|
-
|
|
586
|
+
WebhookSubscription,
|
|
501
587
|
parse_obj_as(
|
|
502
|
-
type_=
|
|
588
|
+
type_=WebhookSubscription, # type: ignore
|
|
503
589
|
object_=_response.json(),
|
|
504
590
|
),
|
|
505
591
|
)
|
|
506
592
|
return HttpResponse(response=_response, data=_data)
|
|
507
|
-
if _response.status_code ==
|
|
508
|
-
raise
|
|
593
|
+
if _response.status_code == 404:
|
|
594
|
+
raise NotFoundError(
|
|
509
595
|
headers=dict(_response.headers),
|
|
510
596
|
body=typing.cast(
|
|
511
|
-
|
|
597
|
+
NotFoundErrorResponse,
|
|
512
598
|
parse_obj_as(
|
|
513
|
-
type_=
|
|
599
|
+
type_=NotFoundErrorResponse, # type: ignore
|
|
514
600
|
object_=_response.json(),
|
|
515
601
|
),
|
|
516
602
|
),
|
|
517
603
|
)
|
|
518
|
-
_response_json = _response.json()
|
|
519
|
-
except JSONDecodeError:
|
|
520
|
-
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
521
|
-
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
522
|
-
|
|
523
|
-
def enable_subscription(
|
|
524
|
-
self,
|
|
525
|
-
subscription_id: str,
|
|
526
|
-
*,
|
|
527
|
-
request: typing.Optional[EnableEndpointRequest] = None,
|
|
528
|
-
request_options: typing.Optional[RequestOptions] = None,
|
|
529
|
-
) -> HttpResponse[EndpointOut]:
|
|
530
|
-
"""
|
|
531
|
-
Enable a disabled webhook subscription, optionally recovering failed messages.
|
|
532
|
-
|
|
533
|
-
Args:
|
|
534
|
-
subscription_id: The ID of the subscription to enable.
|
|
535
|
-
request: Optional request with recovery time range.
|
|
536
|
-
ctx: The API context containing organization info.
|
|
537
|
-
|
|
538
|
-
Returns:
|
|
539
|
-
The enabled subscription.
|
|
540
|
-
|
|
541
|
-
Parameters
|
|
542
|
-
----------
|
|
543
|
-
subscription_id : str
|
|
544
|
-
|
|
545
|
-
request : typing.Optional[EnableEndpointRequest]
|
|
546
|
-
|
|
547
|
-
request_options : typing.Optional[RequestOptions]
|
|
548
|
-
Request-specific configuration.
|
|
549
|
-
|
|
550
|
-
Returns
|
|
551
|
-
-------
|
|
552
|
-
HttpResponse[EndpointOut]
|
|
553
|
-
Successful Response
|
|
554
|
-
"""
|
|
555
|
-
_response = self._client_wrapper.httpx_client.request(
|
|
556
|
-
f"events/subscriptions/{jsonable_encoder(subscription_id)}/enable",
|
|
557
|
-
method="POST",
|
|
558
|
-
json=convert_and_respect_annotation_metadata(
|
|
559
|
-
object_=request, annotation=EnableEndpointRequest, direction="write"
|
|
560
|
-
),
|
|
561
|
-
headers={
|
|
562
|
-
"content-type": "application/json",
|
|
563
|
-
},
|
|
564
|
-
request_options=request_options,
|
|
565
|
-
omit=OMIT,
|
|
566
|
-
)
|
|
567
|
-
try:
|
|
568
|
-
if 200 <= _response.status_code < 300:
|
|
569
|
-
_data = typing.cast(
|
|
570
|
-
EndpointOut,
|
|
571
|
-
parse_obj_as(
|
|
572
|
-
type_=EndpointOut, # type: ignore
|
|
573
|
-
object_=_response.json(),
|
|
574
|
-
),
|
|
575
|
-
)
|
|
576
|
-
return HttpResponse(response=_response, data=_data)
|
|
577
604
|
if _response.status_code == 422:
|
|
578
605
|
raise UnprocessableEntityError(
|
|
579
606
|
headers=dict(_response.headers),
|
|
580
607
|
body=typing.cast(
|
|
581
|
-
|
|
608
|
+
typing.Optional[typing.Any],
|
|
582
609
|
parse_obj_as(
|
|
583
|
-
type_=
|
|
610
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
584
611
|
object_=_response.json(),
|
|
585
612
|
),
|
|
586
613
|
),
|
|
587
614
|
)
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
591
|
-
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
592
|
-
|
|
593
|
-
def get_subscription_secret(
|
|
594
|
-
self, subscription_id: str, *, request_options: typing.Optional[RequestOptions] = None
|
|
595
|
-
) -> HttpResponse[EndpointSecretOut]:
|
|
596
|
-
"""
|
|
597
|
-
Get the signing secret for a webhook subscription.
|
|
598
|
-
|
|
599
|
-
Args:
|
|
600
|
-
subscription_id: The ID of the subscription.
|
|
601
|
-
ctx: The API context containing organization info.
|
|
602
|
-
|
|
603
|
-
Returns:
|
|
604
|
-
The subscription's signing secret.
|
|
605
|
-
|
|
606
|
-
Parameters
|
|
607
|
-
----------
|
|
608
|
-
subscription_id : str
|
|
609
|
-
|
|
610
|
-
request_options : typing.Optional[RequestOptions]
|
|
611
|
-
Request-specific configuration.
|
|
612
|
-
|
|
613
|
-
Returns
|
|
614
|
-
-------
|
|
615
|
-
HttpResponse[EndpointSecretOut]
|
|
616
|
-
Successful Response
|
|
617
|
-
"""
|
|
618
|
-
_response = self._client_wrapper.httpx_client.request(
|
|
619
|
-
f"events/subscriptions/{jsonable_encoder(subscription_id)}/secret",
|
|
620
|
-
method="GET",
|
|
621
|
-
request_options=request_options,
|
|
622
|
-
)
|
|
623
|
-
try:
|
|
624
|
-
if 200 <= _response.status_code < 300:
|
|
625
|
-
_data = typing.cast(
|
|
626
|
-
EndpointSecretOut,
|
|
627
|
-
parse_obj_as(
|
|
628
|
-
type_=EndpointSecretOut, # type: ignore
|
|
629
|
-
object_=_response.json(),
|
|
630
|
-
),
|
|
631
|
-
)
|
|
632
|
-
return HttpResponse(response=_response, data=_data)
|
|
633
|
-
if _response.status_code == 422:
|
|
634
|
-
raise UnprocessableEntityError(
|
|
615
|
+
if _response.status_code == 429:
|
|
616
|
+
raise TooManyRequestsError(
|
|
635
617
|
headers=dict(_response.headers),
|
|
636
618
|
body=typing.cast(
|
|
637
|
-
|
|
619
|
+
RateLimitErrorResponse,
|
|
638
620
|
parse_obj_as(
|
|
639
|
-
type_=
|
|
621
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
640
622
|
object_=_response.json(),
|
|
641
623
|
),
|
|
642
624
|
),
|
|
@@ -653,37 +635,38 @@ class RawEventsClient:
|
|
|
653
635
|
since: dt.datetime,
|
|
654
636
|
until: typing.Optional[dt.datetime] = OMIT,
|
|
655
637
|
request_options: typing.Optional[RequestOptions] = None,
|
|
656
|
-
) -> HttpResponse[
|
|
638
|
+
) -> HttpResponse[RecoveryTask]:
|
|
657
639
|
"""
|
|
658
|
-
|
|
640
|
+
Retry failed message deliveries for a webhook subscription.
|
|
659
641
|
|
|
660
|
-
|
|
661
|
-
time.
|
|
662
|
-
failed while the endpoint was down.
|
|
642
|
+
Triggers a recovery process that replays all failed messages within the
|
|
643
|
+
specified time window. This is useful when:
|
|
663
644
|
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
ctx: The API context containing organization info.
|
|
645
|
+
- Your endpoint was temporarily down and you want to catch up
|
|
646
|
+
- You've fixed a bug in your webhook handler
|
|
647
|
+
- You want to reprocess events after re-enabling a disabled subscription
|
|
668
648
|
|
|
669
|
-
|
|
670
|
-
|
|
649
|
+
Messages are retried in chronological order. Successfully delivered messages
|
|
650
|
+
are skipped; only failed or pending messages are retried.
|
|
671
651
|
|
|
672
652
|
Parameters
|
|
673
653
|
----------
|
|
674
654
|
subscription_id : str
|
|
655
|
+
The unique identifier of the subscription to recover messages for (UUID).
|
|
675
656
|
|
|
676
657
|
since : dt.datetime
|
|
658
|
+
Start of the recovery time window (inclusive). All failed messages from this time onward will be retried.
|
|
677
659
|
|
|
678
660
|
until : typing.Optional[dt.datetime]
|
|
661
|
+
End of the recovery time window (exclusive). If not specified, recovers all failed messages up to now.
|
|
679
662
|
|
|
680
663
|
request_options : typing.Optional[RequestOptions]
|
|
681
664
|
Request-specific configuration.
|
|
682
665
|
|
|
683
666
|
Returns
|
|
684
667
|
-------
|
|
685
|
-
HttpResponse[
|
|
686
|
-
|
|
668
|
+
HttpResponse[RecoveryTask]
|
|
669
|
+
Recovery task information
|
|
687
670
|
"""
|
|
688
671
|
_response = self._client_wrapper.httpx_client.request(
|
|
689
672
|
f"events/subscriptions/{jsonable_encoder(subscription_id)}/recover",
|
|
@@ -701,20 +684,42 @@ class RawEventsClient:
|
|
|
701
684
|
try:
|
|
702
685
|
if 200 <= _response.status_code < 300:
|
|
703
686
|
_data = typing.cast(
|
|
704
|
-
|
|
687
|
+
RecoveryTask,
|
|
705
688
|
parse_obj_as(
|
|
706
|
-
type_=
|
|
689
|
+
type_=RecoveryTask, # type: ignore
|
|
707
690
|
object_=_response.json(),
|
|
708
691
|
),
|
|
709
692
|
)
|
|
710
693
|
return HttpResponse(response=_response, data=_data)
|
|
694
|
+
if _response.status_code == 404:
|
|
695
|
+
raise NotFoundError(
|
|
696
|
+
headers=dict(_response.headers),
|
|
697
|
+
body=typing.cast(
|
|
698
|
+
NotFoundErrorResponse,
|
|
699
|
+
parse_obj_as(
|
|
700
|
+
type_=NotFoundErrorResponse, # type: ignore
|
|
701
|
+
object_=_response.json(),
|
|
702
|
+
),
|
|
703
|
+
),
|
|
704
|
+
)
|
|
711
705
|
if _response.status_code == 422:
|
|
712
706
|
raise UnprocessableEntityError(
|
|
713
707
|
headers=dict(_response.headers),
|
|
714
708
|
body=typing.cast(
|
|
715
|
-
|
|
709
|
+
typing.Optional[typing.Any],
|
|
710
|
+
parse_obj_as(
|
|
711
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
712
|
+
object_=_response.json(),
|
|
713
|
+
),
|
|
714
|
+
),
|
|
715
|
+
)
|
|
716
|
+
if _response.status_code == 429:
|
|
717
|
+
raise TooManyRequestsError(
|
|
718
|
+
headers=dict(_response.headers),
|
|
719
|
+
body=typing.cast(
|
|
720
|
+
RateLimitErrorResponse,
|
|
716
721
|
parse_obj_as(
|
|
717
|
-
type_=
|
|
722
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
718
723
|
object_=_response.json(),
|
|
719
724
|
),
|
|
720
725
|
),
|
|
@@ -734,28 +739,29 @@ class AsyncRawEventsClient:
|
|
|
734
739
|
*,
|
|
735
740
|
event_types: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
|
|
736
741
|
request_options: typing.Optional[RequestOptions] = None,
|
|
737
|
-
) -> AsyncHttpResponse[typing.List[
|
|
742
|
+
) -> AsyncHttpResponse[typing.List[EventMessage]]:
|
|
738
743
|
"""
|
|
739
|
-
|
|
744
|
+
Retrieve all event messages for your organization.
|
|
740
745
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
746
|
+
Event messages represent webhook payloads that were sent (or attempted to be sent)
|
|
747
|
+
to your subscribed endpoints. Each message contains the event type, payload data,
|
|
748
|
+
and delivery status information.
|
|
744
749
|
|
|
745
|
-
|
|
746
|
-
|
|
750
|
+
Use the `event_types` query parameter to filter messages by specific event types,
|
|
751
|
+
such as `sync.completed` or `sync.failed`.
|
|
747
752
|
|
|
748
753
|
Parameters
|
|
749
754
|
----------
|
|
750
755
|
event_types : typing.Optional[typing.Union[str, typing.Sequence[str]]]
|
|
756
|
+
Filter messages by event type(s). Accepts multiple values, e.g., `?event_types=sync.completed&event_types=sync.failed`.
|
|
751
757
|
|
|
752
758
|
request_options : typing.Optional[RequestOptions]
|
|
753
759
|
Request-specific configuration.
|
|
754
760
|
|
|
755
761
|
Returns
|
|
756
762
|
-------
|
|
757
|
-
AsyncHttpResponse[typing.List[
|
|
758
|
-
|
|
763
|
+
AsyncHttpResponse[typing.List[EventMessage]]
|
|
764
|
+
List of event messages
|
|
759
765
|
"""
|
|
760
766
|
_response = await self._client_wrapper.httpx_client.request(
|
|
761
767
|
"events/messages",
|
|
@@ -768,9 +774,9 @@ class AsyncRawEventsClient:
|
|
|
768
774
|
try:
|
|
769
775
|
if 200 <= _response.status_code < 300:
|
|
770
776
|
_data = typing.cast(
|
|
771
|
-
typing.List[
|
|
777
|
+
typing.List[EventMessage],
|
|
772
778
|
parse_obj_as(
|
|
773
|
-
type_=typing.List[
|
|
779
|
+
type_=typing.List[EventMessage], # type: ignore
|
|
774
780
|
object_=_response.json(),
|
|
775
781
|
),
|
|
776
782
|
)
|
|
@@ -779,9 +785,20 @@ class AsyncRawEventsClient:
|
|
|
779
785
|
raise UnprocessableEntityError(
|
|
780
786
|
headers=dict(_response.headers),
|
|
781
787
|
body=typing.cast(
|
|
782
|
-
|
|
788
|
+
typing.Optional[typing.Any],
|
|
783
789
|
parse_obj_as(
|
|
784
|
-
type_=
|
|
790
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
791
|
+
object_=_response.json(),
|
|
792
|
+
),
|
|
793
|
+
),
|
|
794
|
+
)
|
|
795
|
+
if _response.status_code == 429:
|
|
796
|
+
raise TooManyRequestsError(
|
|
797
|
+
headers=dict(_response.headers),
|
|
798
|
+
body=typing.cast(
|
|
799
|
+
RateLimitErrorResponse,
|
|
800
|
+
parse_obj_as(
|
|
801
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
785
802
|
object_=_response.json(),
|
|
786
803
|
),
|
|
787
804
|
),
|
|
@@ -792,108 +809,86 @@ class AsyncRawEventsClient:
|
|
|
792
809
|
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
793
810
|
|
|
794
811
|
async def get_message(
|
|
795
|
-
self,
|
|
796
|
-
|
|
812
|
+
self,
|
|
813
|
+
message_id: str,
|
|
814
|
+
*,
|
|
815
|
+
include_attempts: typing.Optional[bool] = None,
|
|
816
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
817
|
+
) -> AsyncHttpResponse[EventMessageWithAttempts]:
|
|
797
818
|
"""
|
|
798
|
-
|
|
819
|
+
Retrieve a specific event message by its ID.
|
|
799
820
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
821
|
+
Returns the full message details including the event type, payload data,
|
|
822
|
+
timestamp, and delivery channel information. Use this to inspect the
|
|
823
|
+
exact payload that was sent to your webhook endpoints.
|
|
803
824
|
|
|
804
|
-
|
|
805
|
-
|
|
825
|
+
Use `include_attempts=true` to also retrieve delivery attempts for this message,
|
|
826
|
+
which include HTTP response codes, response bodies, and timestamps for debugging
|
|
827
|
+
delivery failures.
|
|
806
828
|
|
|
807
829
|
Parameters
|
|
808
830
|
----------
|
|
809
831
|
message_id : str
|
|
832
|
+
The unique identifier of the message to retrieve (UUID).
|
|
833
|
+
|
|
834
|
+
include_attempts : typing.Optional[bool]
|
|
835
|
+
Include delivery attempts for this message. Each attempt includes the HTTP response code, response body, and timestamp.
|
|
810
836
|
|
|
811
837
|
request_options : typing.Optional[RequestOptions]
|
|
812
838
|
Request-specific configuration.
|
|
813
839
|
|
|
814
840
|
Returns
|
|
815
841
|
-------
|
|
816
|
-
AsyncHttpResponse[
|
|
817
|
-
|
|
842
|
+
AsyncHttpResponse[EventMessageWithAttempts]
|
|
843
|
+
Event message details
|
|
818
844
|
"""
|
|
819
845
|
_response = await self._client_wrapper.httpx_client.request(
|
|
820
846
|
f"events/messages/{jsonable_encoder(message_id)}",
|
|
821
847
|
method="GET",
|
|
848
|
+
params={
|
|
849
|
+
"include_attempts": include_attempts,
|
|
850
|
+
},
|
|
822
851
|
request_options=request_options,
|
|
823
852
|
)
|
|
824
853
|
try:
|
|
825
854
|
if 200 <= _response.status_code < 300:
|
|
826
855
|
_data = typing.cast(
|
|
827
|
-
|
|
856
|
+
EventMessageWithAttempts,
|
|
828
857
|
parse_obj_as(
|
|
829
|
-
type_=
|
|
858
|
+
type_=EventMessageWithAttempts, # type: ignore
|
|
830
859
|
object_=_response.json(),
|
|
831
860
|
),
|
|
832
861
|
)
|
|
833
862
|
return AsyncHttpResponse(response=_response, data=_data)
|
|
834
|
-
if _response.status_code ==
|
|
835
|
-
raise
|
|
863
|
+
if _response.status_code == 404:
|
|
864
|
+
raise NotFoundError(
|
|
836
865
|
headers=dict(_response.headers),
|
|
837
866
|
body=typing.cast(
|
|
838
|
-
|
|
867
|
+
NotFoundErrorResponse,
|
|
839
868
|
parse_obj_as(
|
|
840
|
-
type_=
|
|
869
|
+
type_=NotFoundErrorResponse, # type: ignore
|
|
841
870
|
object_=_response.json(),
|
|
842
871
|
),
|
|
843
872
|
),
|
|
844
873
|
)
|
|
845
|
-
_response_json = _response.json()
|
|
846
|
-
except JSONDecodeError:
|
|
847
|
-
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
848
|
-
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
849
|
-
|
|
850
|
-
async def get_message_attempts(
|
|
851
|
-
self, message_id: str, *, request_options: typing.Optional[RequestOptions] = None
|
|
852
|
-
) -> AsyncHttpResponse[typing.List[MessageAttemptOut]]:
|
|
853
|
-
"""
|
|
854
|
-
Get delivery attempts for a specific message.
|
|
855
|
-
|
|
856
|
-
Args:
|
|
857
|
-
message_id: The ID of the message.
|
|
858
|
-
ctx: The API context containing organization info.
|
|
859
|
-
|
|
860
|
-
Returns:
|
|
861
|
-
List of delivery attempts for this message.
|
|
862
|
-
|
|
863
|
-
Parameters
|
|
864
|
-
----------
|
|
865
|
-
message_id : str
|
|
866
|
-
|
|
867
|
-
request_options : typing.Optional[RequestOptions]
|
|
868
|
-
Request-specific configuration.
|
|
869
|
-
|
|
870
|
-
Returns
|
|
871
|
-
-------
|
|
872
|
-
AsyncHttpResponse[typing.List[MessageAttemptOut]]
|
|
873
|
-
Successful Response
|
|
874
|
-
"""
|
|
875
|
-
_response = await self._client_wrapper.httpx_client.request(
|
|
876
|
-
f"events/messages/{jsonable_encoder(message_id)}/attempts",
|
|
877
|
-
method="GET",
|
|
878
|
-
request_options=request_options,
|
|
879
|
-
)
|
|
880
|
-
try:
|
|
881
|
-
if 200 <= _response.status_code < 300:
|
|
882
|
-
_data = typing.cast(
|
|
883
|
-
typing.List[MessageAttemptOut],
|
|
884
|
-
parse_obj_as(
|
|
885
|
-
type_=typing.List[MessageAttemptOut], # type: ignore
|
|
886
|
-
object_=_response.json(),
|
|
887
|
-
),
|
|
888
|
-
)
|
|
889
|
-
return AsyncHttpResponse(response=_response, data=_data)
|
|
890
874
|
if _response.status_code == 422:
|
|
891
875
|
raise UnprocessableEntityError(
|
|
892
876
|
headers=dict(_response.headers),
|
|
893
877
|
body=typing.cast(
|
|
894
|
-
|
|
878
|
+
typing.Optional[typing.Any],
|
|
879
|
+
parse_obj_as(
|
|
880
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
881
|
+
object_=_response.json(),
|
|
882
|
+
),
|
|
883
|
+
),
|
|
884
|
+
)
|
|
885
|
+
if _response.status_code == 429:
|
|
886
|
+
raise TooManyRequestsError(
|
|
887
|
+
headers=dict(_response.headers),
|
|
888
|
+
body=typing.cast(
|
|
889
|
+
RateLimitErrorResponse,
|
|
895
890
|
parse_obj_as(
|
|
896
|
-
type_=
|
|
891
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
897
892
|
object_=_response.json(),
|
|
898
893
|
),
|
|
899
894
|
),
|
|
@@ -905,15 +900,13 @@ class AsyncRawEventsClient:
|
|
|
905
900
|
|
|
906
901
|
async def get_subscriptions(
|
|
907
902
|
self, *, request_options: typing.Optional[RequestOptions] = None
|
|
908
|
-
) -> AsyncHttpResponse[typing.List[
|
|
903
|
+
) -> AsyncHttpResponse[typing.List[WebhookSubscription]]:
|
|
909
904
|
"""
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
Args:
|
|
913
|
-
ctx: The API context containing organization info.
|
|
905
|
+
List all webhook subscriptions for your organization.
|
|
914
906
|
|
|
915
|
-
Returns
|
|
916
|
-
|
|
907
|
+
Returns all configured webhook endpoints, including their URLs, subscribed
|
|
908
|
+
event types, and current status (enabled/disabled). Use this to audit
|
|
909
|
+
your webhook configuration or find a specific subscription.
|
|
917
910
|
|
|
918
911
|
Parameters
|
|
919
912
|
----------
|
|
@@ -922,8 +915,8 @@ class AsyncRawEventsClient:
|
|
|
922
915
|
|
|
923
916
|
Returns
|
|
924
917
|
-------
|
|
925
|
-
AsyncHttpResponse[typing.List[
|
|
926
|
-
|
|
918
|
+
AsyncHttpResponse[typing.List[WebhookSubscription]]
|
|
919
|
+
List of webhook subscriptions
|
|
927
920
|
"""
|
|
928
921
|
_response = await self._client_wrapper.httpx_client.request(
|
|
929
922
|
"events/subscriptions",
|
|
@@ -933,9 +926,9 @@ class AsyncRawEventsClient:
|
|
|
933
926
|
try:
|
|
934
927
|
if 200 <= _response.status_code < 300:
|
|
935
928
|
_data = typing.cast(
|
|
936
|
-
typing.List[
|
|
929
|
+
typing.List[WebhookSubscription],
|
|
937
930
|
parse_obj_as(
|
|
938
|
-
type_=typing.List[
|
|
931
|
+
type_=typing.List[WebhookSubscription], # type: ignore
|
|
939
932
|
object_=_response.json(),
|
|
940
933
|
),
|
|
941
934
|
)
|
|
@@ -944,9 +937,20 @@ class AsyncRawEventsClient:
|
|
|
944
937
|
raise UnprocessableEntityError(
|
|
945
938
|
headers=dict(_response.headers),
|
|
946
939
|
body=typing.cast(
|
|
947
|
-
|
|
940
|
+
typing.Optional[typing.Any],
|
|
948
941
|
parse_obj_as(
|
|
949
|
-
type_=
|
|
942
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
943
|
+
object_=_response.json(),
|
|
944
|
+
),
|
|
945
|
+
),
|
|
946
|
+
)
|
|
947
|
+
if _response.status_code == 429:
|
|
948
|
+
raise TooManyRequestsError(
|
|
949
|
+
headers=dict(_response.headers),
|
|
950
|
+
body=typing.cast(
|
|
951
|
+
RateLimitErrorResponse,
|
|
952
|
+
parse_obj_as(
|
|
953
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
950
954
|
object_=_response.json(),
|
|
951
955
|
),
|
|
952
956
|
),
|
|
@@ -963,32 +967,38 @@ class AsyncRawEventsClient:
|
|
|
963
967
|
event_types: typing.Sequence[EventType],
|
|
964
968
|
secret: typing.Optional[str] = OMIT,
|
|
965
969
|
request_options: typing.Optional[RequestOptions] = None,
|
|
966
|
-
) -> AsyncHttpResponse[
|
|
970
|
+
) -> AsyncHttpResponse[WebhookSubscription]:
|
|
967
971
|
"""
|
|
968
972
|
Create a new webhook subscription.
|
|
969
973
|
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
974
|
+
Webhook subscriptions allow you to receive real-time notifications when events
|
|
975
|
+
occur in Airweave. When you create a subscription, you specify:
|
|
976
|
+
|
|
977
|
+
- **URL**: The HTTPS endpoint where events will be delivered
|
|
978
|
+
- **Event Types**: Which events you want to receive (e.g., `sync.completed`, `sync.failed`)
|
|
979
|
+
- **Secret** (optional): A custom signing secret for verifying webhook signatures
|
|
973
980
|
|
|
974
|
-
|
|
975
|
-
|
|
981
|
+
After creation, Airweave will send HTTP POST requests to your URL whenever
|
|
982
|
+
matching events occur. Each request includes a signature header for verification.
|
|
976
983
|
|
|
977
984
|
Parameters
|
|
978
985
|
----------
|
|
979
986
|
url : str
|
|
987
|
+
The HTTPS URL where webhook events will be delivered. Must be a publicly accessible endpoint that returns a 2xx status code.
|
|
980
988
|
|
|
981
989
|
event_types : typing.Sequence[EventType]
|
|
990
|
+
List of event types to subscribe to. Events not in this list will not be delivered to this subscription. Available types: `sync.pending`, `sync.running`, `sync.completed`, `sync.failed`, `sync.cancelled`.
|
|
982
991
|
|
|
983
992
|
secret : typing.Optional[str]
|
|
993
|
+
Optional custom signing secret for webhook signature verification. If not provided, a secure secret will be auto-generated. Must be at least 24 characters if specified.
|
|
984
994
|
|
|
985
995
|
request_options : typing.Optional[RequestOptions]
|
|
986
996
|
Request-specific configuration.
|
|
987
997
|
|
|
988
998
|
Returns
|
|
989
999
|
-------
|
|
990
|
-
AsyncHttpResponse[
|
|
991
|
-
|
|
1000
|
+
AsyncHttpResponse[WebhookSubscription]
|
|
1001
|
+
Created subscription
|
|
992
1002
|
"""
|
|
993
1003
|
_response = await self._client_wrapper.httpx_client.request(
|
|
994
1004
|
"events/subscriptions",
|
|
@@ -1007,9 +1017,9 @@ class AsyncRawEventsClient:
|
|
|
1007
1017
|
try:
|
|
1008
1018
|
if 200 <= _response.status_code < 300:
|
|
1009
1019
|
_data = typing.cast(
|
|
1010
|
-
|
|
1020
|
+
WebhookSubscription,
|
|
1011
1021
|
parse_obj_as(
|
|
1012
|
-
type_=
|
|
1022
|
+
type_=WebhookSubscription, # type: ignore
|
|
1013
1023
|
object_=_response.json(),
|
|
1014
1024
|
),
|
|
1015
1025
|
)
|
|
@@ -1018,9 +1028,20 @@ class AsyncRawEventsClient:
|
|
|
1018
1028
|
raise UnprocessableEntityError(
|
|
1019
1029
|
headers=dict(_response.headers),
|
|
1020
1030
|
body=typing.cast(
|
|
1021
|
-
|
|
1031
|
+
typing.Optional[typing.Any],
|
|
1022
1032
|
parse_obj_as(
|
|
1023
|
-
type_=
|
|
1033
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
1034
|
+
object_=_response.json(),
|
|
1035
|
+
),
|
|
1036
|
+
),
|
|
1037
|
+
)
|
|
1038
|
+
if _response.status_code == 429:
|
|
1039
|
+
raise TooManyRequestsError(
|
|
1040
|
+
headers=dict(_response.headers),
|
|
1041
|
+
body=typing.cast(
|
|
1042
|
+
RateLimitErrorResponse,
|
|
1043
|
+
parse_obj_as(
|
|
1044
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
1024
1045
|
object_=_response.json(),
|
|
1025
1046
|
),
|
|
1026
1047
|
),
|
|
@@ -1031,52 +1052,85 @@ class AsyncRawEventsClient:
|
|
|
1031
1052
|
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
1032
1053
|
|
|
1033
1054
|
async def get_subscription(
|
|
1034
|
-
self,
|
|
1035
|
-
|
|
1055
|
+
self,
|
|
1056
|
+
subscription_id: str,
|
|
1057
|
+
*,
|
|
1058
|
+
include_secret: typing.Optional[bool] = None,
|
|
1059
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
1060
|
+
) -> AsyncHttpResponse[WebhookSubscription]:
|
|
1036
1061
|
"""
|
|
1037
|
-
|
|
1062
|
+
Retrieve a specific webhook subscription with its recent delivery attempts.
|
|
1038
1063
|
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1064
|
+
Returns the subscription configuration along with a history of message delivery
|
|
1065
|
+
attempts. This is useful for debugging delivery issues or verifying that your
|
|
1066
|
+
endpoint is correctly receiving events.
|
|
1042
1067
|
|
|
1043
|
-
|
|
1044
|
-
|
|
1068
|
+
Use `include_secret=true` to also retrieve the signing secret for webhook
|
|
1069
|
+
signature verification. Keep this secret secure.
|
|
1045
1070
|
|
|
1046
1071
|
Parameters
|
|
1047
1072
|
----------
|
|
1048
1073
|
subscription_id : str
|
|
1074
|
+
The unique identifier of the subscription to retrieve (UUID).
|
|
1075
|
+
|
|
1076
|
+
include_secret : typing.Optional[bool]
|
|
1077
|
+
Include the signing secret for webhook signature verification. Keep this secret secure and use it to verify the 'svix-signature' header.
|
|
1049
1078
|
|
|
1050
1079
|
request_options : typing.Optional[RequestOptions]
|
|
1051
1080
|
Request-specific configuration.
|
|
1052
1081
|
|
|
1053
1082
|
Returns
|
|
1054
1083
|
-------
|
|
1055
|
-
AsyncHttpResponse[
|
|
1056
|
-
|
|
1084
|
+
AsyncHttpResponse[WebhookSubscription]
|
|
1085
|
+
Subscription with delivery attempts
|
|
1057
1086
|
"""
|
|
1058
1087
|
_response = await self._client_wrapper.httpx_client.request(
|
|
1059
1088
|
f"events/subscriptions/{jsonable_encoder(subscription_id)}",
|
|
1060
1089
|
method="GET",
|
|
1090
|
+
params={
|
|
1091
|
+
"include_secret": include_secret,
|
|
1092
|
+
},
|
|
1061
1093
|
request_options=request_options,
|
|
1062
1094
|
)
|
|
1063
1095
|
try:
|
|
1064
1096
|
if 200 <= _response.status_code < 300:
|
|
1065
1097
|
_data = typing.cast(
|
|
1066
|
-
|
|
1098
|
+
WebhookSubscription,
|
|
1067
1099
|
parse_obj_as(
|
|
1068
|
-
type_=
|
|
1100
|
+
type_=WebhookSubscription, # type: ignore
|
|
1069
1101
|
object_=_response.json(),
|
|
1070
1102
|
),
|
|
1071
1103
|
)
|
|
1072
1104
|
return AsyncHttpResponse(response=_response, data=_data)
|
|
1105
|
+
if _response.status_code == 404:
|
|
1106
|
+
raise NotFoundError(
|
|
1107
|
+
headers=dict(_response.headers),
|
|
1108
|
+
body=typing.cast(
|
|
1109
|
+
NotFoundErrorResponse,
|
|
1110
|
+
parse_obj_as(
|
|
1111
|
+
type_=NotFoundErrorResponse, # type: ignore
|
|
1112
|
+
object_=_response.json(),
|
|
1113
|
+
),
|
|
1114
|
+
),
|
|
1115
|
+
)
|
|
1073
1116
|
if _response.status_code == 422:
|
|
1074
1117
|
raise UnprocessableEntityError(
|
|
1075
1118
|
headers=dict(_response.headers),
|
|
1076
1119
|
body=typing.cast(
|
|
1077
|
-
|
|
1120
|
+
typing.Optional[typing.Any],
|
|
1078
1121
|
parse_obj_as(
|
|
1079
|
-
type_=
|
|
1122
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
1123
|
+
object_=_response.json(),
|
|
1124
|
+
),
|
|
1125
|
+
),
|
|
1126
|
+
)
|
|
1127
|
+
if _response.status_code == 429:
|
|
1128
|
+
raise TooManyRequestsError(
|
|
1129
|
+
headers=dict(_response.headers),
|
|
1130
|
+
body=typing.cast(
|
|
1131
|
+
RateLimitErrorResponse,
|
|
1132
|
+
parse_obj_as(
|
|
1133
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
1080
1134
|
object_=_response.json(),
|
|
1081
1135
|
),
|
|
1082
1136
|
),
|
|
@@ -1088,25 +1142,28 @@ class AsyncRawEventsClient:
|
|
|
1088
1142
|
|
|
1089
1143
|
async def delete_subscription(
|
|
1090
1144
|
self, subscription_id: str, *, request_options: typing.Optional[RequestOptions] = None
|
|
1091
|
-
) -> AsyncHttpResponse[
|
|
1145
|
+
) -> AsyncHttpResponse[WebhookSubscription]:
|
|
1092
1146
|
"""
|
|
1093
|
-
|
|
1147
|
+
Permanently delete a webhook subscription.
|
|
1094
1148
|
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1149
|
+
Once deleted, Airweave will stop sending events to this endpoint immediately.
|
|
1150
|
+
This action cannot be undone. Any pending message deliveries will be cancelled.
|
|
1151
|
+
|
|
1152
|
+
If you want to temporarily stop receiving events, consider disabling the
|
|
1153
|
+
subscription instead using the PATCH endpoint.
|
|
1098
1154
|
|
|
1099
1155
|
Parameters
|
|
1100
1156
|
----------
|
|
1101
1157
|
subscription_id : str
|
|
1158
|
+
The unique identifier of the subscription to delete (UUID).
|
|
1102
1159
|
|
|
1103
1160
|
request_options : typing.Optional[RequestOptions]
|
|
1104
1161
|
Request-specific configuration.
|
|
1105
1162
|
|
|
1106
1163
|
Returns
|
|
1107
1164
|
-------
|
|
1108
|
-
AsyncHttpResponse[
|
|
1109
|
-
|
|
1165
|
+
AsyncHttpResponse[WebhookSubscription]
|
|
1166
|
+
Deleted subscription
|
|
1110
1167
|
"""
|
|
1111
1168
|
_response = await self._client_wrapper.httpx_client.request(
|
|
1112
1169
|
f"events/subscriptions/{jsonable_encoder(subscription_id)}",
|
|
@@ -1114,24 +1171,44 @@ class AsyncRawEventsClient:
|
|
|
1114
1171
|
request_options=request_options,
|
|
1115
1172
|
)
|
|
1116
1173
|
try:
|
|
1117
|
-
if _response is None or not _response.text.strip():
|
|
1118
|
-
return AsyncHttpResponse(response=_response, data=None)
|
|
1119
1174
|
if 200 <= _response.status_code < 300:
|
|
1120
1175
|
_data = typing.cast(
|
|
1121
|
-
|
|
1176
|
+
WebhookSubscription,
|
|
1122
1177
|
parse_obj_as(
|
|
1123
|
-
type_=
|
|
1178
|
+
type_=WebhookSubscription, # type: ignore
|
|
1124
1179
|
object_=_response.json(),
|
|
1125
1180
|
),
|
|
1126
1181
|
)
|
|
1127
1182
|
return AsyncHttpResponse(response=_response, data=_data)
|
|
1183
|
+
if _response.status_code == 404:
|
|
1184
|
+
raise NotFoundError(
|
|
1185
|
+
headers=dict(_response.headers),
|
|
1186
|
+
body=typing.cast(
|
|
1187
|
+
NotFoundErrorResponse,
|
|
1188
|
+
parse_obj_as(
|
|
1189
|
+
type_=NotFoundErrorResponse, # type: ignore
|
|
1190
|
+
object_=_response.json(),
|
|
1191
|
+
),
|
|
1192
|
+
),
|
|
1193
|
+
)
|
|
1128
1194
|
if _response.status_code == 422:
|
|
1129
1195
|
raise UnprocessableEntityError(
|
|
1130
1196
|
headers=dict(_response.headers),
|
|
1131
1197
|
body=typing.cast(
|
|
1132
|
-
|
|
1198
|
+
typing.Optional[typing.Any],
|
|
1133
1199
|
parse_obj_as(
|
|
1134
|
-
type_=
|
|
1200
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
1201
|
+
object_=_response.json(),
|
|
1202
|
+
),
|
|
1203
|
+
),
|
|
1204
|
+
)
|
|
1205
|
+
if _response.status_code == 429:
|
|
1206
|
+
raise TooManyRequestsError(
|
|
1207
|
+
headers=dict(_response.headers),
|
|
1208
|
+
body=typing.cast(
|
|
1209
|
+
RateLimitErrorResponse,
|
|
1210
|
+
parse_obj_as(
|
|
1211
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
1135
1212
|
object_=_response.json(),
|
|
1136
1213
|
),
|
|
1137
1214
|
),
|
|
@@ -1148,36 +1225,50 @@ class AsyncRawEventsClient:
|
|
|
1148
1225
|
url: typing.Optional[str] = OMIT,
|
|
1149
1226
|
event_types: typing.Optional[typing.Sequence[EventType]] = OMIT,
|
|
1150
1227
|
disabled: typing.Optional[bool] = OMIT,
|
|
1228
|
+
recover_since: typing.Optional[dt.datetime] = OMIT,
|
|
1151
1229
|
request_options: typing.Optional[RequestOptions] = None,
|
|
1152
|
-
) -> AsyncHttpResponse[
|
|
1230
|
+
) -> AsyncHttpResponse[WebhookSubscription]:
|
|
1153
1231
|
"""
|
|
1154
|
-
Update
|
|
1232
|
+
Update an existing webhook subscription.
|
|
1233
|
+
|
|
1234
|
+
Use this endpoint to modify a subscription's configuration. You can:
|
|
1155
1235
|
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1236
|
+
- **Change the URL**: Update where events are delivered
|
|
1237
|
+
- **Update event types**: Modify which events trigger notifications
|
|
1238
|
+
- **Enable/disable**: Temporarily pause delivery without deleting the subscription
|
|
1239
|
+
- **Recover messages**: When re-enabling, optionally recover missed messages
|
|
1160
1240
|
|
|
1161
|
-
|
|
1162
|
-
|
|
1241
|
+
Only include the fields you want to change. Omitted fields will retain their
|
|
1242
|
+
current values.
|
|
1243
|
+
|
|
1244
|
+
When re-enabling a subscription (`disabled: false`), you can optionally provide
|
|
1245
|
+
`recover_since` to automatically retry all messages that were generated while
|
|
1246
|
+
the subscription was disabled.
|
|
1163
1247
|
|
|
1164
1248
|
Parameters
|
|
1165
1249
|
----------
|
|
1166
1250
|
subscription_id : str
|
|
1251
|
+
The unique identifier of the subscription to update (UUID).
|
|
1167
1252
|
|
|
1168
1253
|
url : typing.Optional[str]
|
|
1254
|
+
New URL for webhook delivery. Must be a publicly accessible HTTPS endpoint.
|
|
1169
1255
|
|
|
1170
1256
|
event_types : typing.Optional[typing.Sequence[EventType]]
|
|
1257
|
+
New list of event types to subscribe to. This replaces the existing list entirely.
|
|
1171
1258
|
|
|
1172
1259
|
disabled : typing.Optional[bool]
|
|
1260
|
+
Set to `true` to pause delivery to this subscription, or `false` to resume. Disabled subscriptions will not receive events.
|
|
1261
|
+
|
|
1262
|
+
recover_since : typing.Optional[dt.datetime]
|
|
1263
|
+
When re-enabling a subscription (`disabled: false`), optionally recover failed messages from this timestamp. Only applies when enabling.
|
|
1173
1264
|
|
|
1174
1265
|
request_options : typing.Optional[RequestOptions]
|
|
1175
1266
|
Request-specific configuration.
|
|
1176
1267
|
|
|
1177
1268
|
Returns
|
|
1178
1269
|
-------
|
|
1179
|
-
AsyncHttpResponse[
|
|
1180
|
-
|
|
1270
|
+
AsyncHttpResponse[WebhookSubscription]
|
|
1271
|
+
Updated subscription
|
|
1181
1272
|
"""
|
|
1182
1273
|
_response = await self._client_wrapper.httpx_client.request(
|
|
1183
1274
|
f"events/subscriptions/{jsonable_encoder(subscription_id)}",
|
|
@@ -1186,6 +1277,7 @@ class AsyncRawEventsClient:
|
|
|
1186
1277
|
"url": url,
|
|
1187
1278
|
"event_types": event_types,
|
|
1188
1279
|
"disabled": disabled,
|
|
1280
|
+
"recover_since": recover_since,
|
|
1189
1281
|
},
|
|
1190
1282
|
headers={
|
|
1191
1283
|
"content-type": "application/json",
|
|
@@ -1196,146 +1288,42 @@ class AsyncRawEventsClient:
|
|
|
1196
1288
|
try:
|
|
1197
1289
|
if 200 <= _response.status_code < 300:
|
|
1198
1290
|
_data = typing.cast(
|
|
1199
|
-
|
|
1291
|
+
WebhookSubscription,
|
|
1200
1292
|
parse_obj_as(
|
|
1201
|
-
type_=
|
|
1293
|
+
type_=WebhookSubscription, # type: ignore
|
|
1202
1294
|
object_=_response.json(),
|
|
1203
1295
|
),
|
|
1204
1296
|
)
|
|
1205
1297
|
return AsyncHttpResponse(response=_response, data=_data)
|
|
1206
|
-
if _response.status_code ==
|
|
1207
|
-
raise
|
|
1298
|
+
if _response.status_code == 404:
|
|
1299
|
+
raise NotFoundError(
|
|
1208
1300
|
headers=dict(_response.headers),
|
|
1209
1301
|
body=typing.cast(
|
|
1210
|
-
|
|
1302
|
+
NotFoundErrorResponse,
|
|
1211
1303
|
parse_obj_as(
|
|
1212
|
-
type_=
|
|
1304
|
+
type_=NotFoundErrorResponse, # type: ignore
|
|
1213
1305
|
object_=_response.json(),
|
|
1214
1306
|
),
|
|
1215
1307
|
),
|
|
1216
1308
|
)
|
|
1217
|
-
_response_json = _response.json()
|
|
1218
|
-
except JSONDecodeError:
|
|
1219
|
-
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
1220
|
-
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
1221
|
-
|
|
1222
|
-
async def enable_subscription(
|
|
1223
|
-
self,
|
|
1224
|
-
subscription_id: str,
|
|
1225
|
-
*,
|
|
1226
|
-
request: typing.Optional[EnableEndpointRequest] = None,
|
|
1227
|
-
request_options: typing.Optional[RequestOptions] = None,
|
|
1228
|
-
) -> AsyncHttpResponse[EndpointOut]:
|
|
1229
|
-
"""
|
|
1230
|
-
Enable a disabled webhook subscription, optionally recovering failed messages.
|
|
1231
|
-
|
|
1232
|
-
Args:
|
|
1233
|
-
subscription_id: The ID of the subscription to enable.
|
|
1234
|
-
request: Optional request with recovery time range.
|
|
1235
|
-
ctx: The API context containing organization info.
|
|
1236
|
-
|
|
1237
|
-
Returns:
|
|
1238
|
-
The enabled subscription.
|
|
1239
|
-
|
|
1240
|
-
Parameters
|
|
1241
|
-
----------
|
|
1242
|
-
subscription_id : str
|
|
1243
|
-
|
|
1244
|
-
request : typing.Optional[EnableEndpointRequest]
|
|
1245
|
-
|
|
1246
|
-
request_options : typing.Optional[RequestOptions]
|
|
1247
|
-
Request-specific configuration.
|
|
1248
|
-
|
|
1249
|
-
Returns
|
|
1250
|
-
-------
|
|
1251
|
-
AsyncHttpResponse[EndpointOut]
|
|
1252
|
-
Successful Response
|
|
1253
|
-
"""
|
|
1254
|
-
_response = await self._client_wrapper.httpx_client.request(
|
|
1255
|
-
f"events/subscriptions/{jsonable_encoder(subscription_id)}/enable",
|
|
1256
|
-
method="POST",
|
|
1257
|
-
json=convert_and_respect_annotation_metadata(
|
|
1258
|
-
object_=request, annotation=EnableEndpointRequest, direction="write"
|
|
1259
|
-
),
|
|
1260
|
-
headers={
|
|
1261
|
-
"content-type": "application/json",
|
|
1262
|
-
},
|
|
1263
|
-
request_options=request_options,
|
|
1264
|
-
omit=OMIT,
|
|
1265
|
-
)
|
|
1266
|
-
try:
|
|
1267
|
-
if 200 <= _response.status_code < 300:
|
|
1268
|
-
_data = typing.cast(
|
|
1269
|
-
EndpointOut,
|
|
1270
|
-
parse_obj_as(
|
|
1271
|
-
type_=EndpointOut, # type: ignore
|
|
1272
|
-
object_=_response.json(),
|
|
1273
|
-
),
|
|
1274
|
-
)
|
|
1275
|
-
return AsyncHttpResponse(response=_response, data=_data)
|
|
1276
1309
|
if _response.status_code == 422:
|
|
1277
1310
|
raise UnprocessableEntityError(
|
|
1278
1311
|
headers=dict(_response.headers),
|
|
1279
1312
|
body=typing.cast(
|
|
1280
|
-
|
|
1313
|
+
typing.Optional[typing.Any],
|
|
1281
1314
|
parse_obj_as(
|
|
1282
|
-
type_=
|
|
1315
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
1283
1316
|
object_=_response.json(),
|
|
1284
1317
|
),
|
|
1285
1318
|
),
|
|
1286
1319
|
)
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
|
|
1290
|
-
raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
|
|
1291
|
-
|
|
1292
|
-
async def get_subscription_secret(
|
|
1293
|
-
self, subscription_id: str, *, request_options: typing.Optional[RequestOptions] = None
|
|
1294
|
-
) -> AsyncHttpResponse[EndpointSecretOut]:
|
|
1295
|
-
"""
|
|
1296
|
-
Get the signing secret for a webhook subscription.
|
|
1297
|
-
|
|
1298
|
-
Args:
|
|
1299
|
-
subscription_id: The ID of the subscription.
|
|
1300
|
-
ctx: The API context containing organization info.
|
|
1301
|
-
|
|
1302
|
-
Returns:
|
|
1303
|
-
The subscription's signing secret.
|
|
1304
|
-
|
|
1305
|
-
Parameters
|
|
1306
|
-
----------
|
|
1307
|
-
subscription_id : str
|
|
1308
|
-
|
|
1309
|
-
request_options : typing.Optional[RequestOptions]
|
|
1310
|
-
Request-specific configuration.
|
|
1311
|
-
|
|
1312
|
-
Returns
|
|
1313
|
-
-------
|
|
1314
|
-
AsyncHttpResponse[EndpointSecretOut]
|
|
1315
|
-
Successful Response
|
|
1316
|
-
"""
|
|
1317
|
-
_response = await self._client_wrapper.httpx_client.request(
|
|
1318
|
-
f"events/subscriptions/{jsonable_encoder(subscription_id)}/secret",
|
|
1319
|
-
method="GET",
|
|
1320
|
-
request_options=request_options,
|
|
1321
|
-
)
|
|
1322
|
-
try:
|
|
1323
|
-
if 200 <= _response.status_code < 300:
|
|
1324
|
-
_data = typing.cast(
|
|
1325
|
-
EndpointSecretOut,
|
|
1326
|
-
parse_obj_as(
|
|
1327
|
-
type_=EndpointSecretOut, # type: ignore
|
|
1328
|
-
object_=_response.json(),
|
|
1329
|
-
),
|
|
1330
|
-
)
|
|
1331
|
-
return AsyncHttpResponse(response=_response, data=_data)
|
|
1332
|
-
if _response.status_code == 422:
|
|
1333
|
-
raise UnprocessableEntityError(
|
|
1320
|
+
if _response.status_code == 429:
|
|
1321
|
+
raise TooManyRequestsError(
|
|
1334
1322
|
headers=dict(_response.headers),
|
|
1335
1323
|
body=typing.cast(
|
|
1336
|
-
|
|
1324
|
+
RateLimitErrorResponse,
|
|
1337
1325
|
parse_obj_as(
|
|
1338
|
-
type_=
|
|
1326
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
1339
1327
|
object_=_response.json(),
|
|
1340
1328
|
),
|
|
1341
1329
|
),
|
|
@@ -1352,37 +1340,38 @@ class AsyncRawEventsClient:
|
|
|
1352
1340
|
since: dt.datetime,
|
|
1353
1341
|
until: typing.Optional[dt.datetime] = OMIT,
|
|
1354
1342
|
request_options: typing.Optional[RequestOptions] = None,
|
|
1355
|
-
) -> AsyncHttpResponse[
|
|
1343
|
+
) -> AsyncHttpResponse[RecoveryTask]:
|
|
1356
1344
|
"""
|
|
1357
|
-
|
|
1345
|
+
Retry failed message deliveries for a webhook subscription.
|
|
1358
1346
|
|
|
1359
|
-
|
|
1360
|
-
time.
|
|
1361
|
-
failed while the endpoint was down.
|
|
1347
|
+
Triggers a recovery process that replays all failed messages within the
|
|
1348
|
+
specified time window. This is useful when:
|
|
1362
1349
|
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
ctx: The API context containing organization info.
|
|
1350
|
+
- Your endpoint was temporarily down and you want to catch up
|
|
1351
|
+
- You've fixed a bug in your webhook handler
|
|
1352
|
+
- You want to reprocess events after re-enabling a disabled subscription
|
|
1367
1353
|
|
|
1368
|
-
|
|
1369
|
-
|
|
1354
|
+
Messages are retried in chronological order. Successfully delivered messages
|
|
1355
|
+
are skipped; only failed or pending messages are retried.
|
|
1370
1356
|
|
|
1371
1357
|
Parameters
|
|
1372
1358
|
----------
|
|
1373
1359
|
subscription_id : str
|
|
1360
|
+
The unique identifier of the subscription to recover messages for (UUID).
|
|
1374
1361
|
|
|
1375
1362
|
since : dt.datetime
|
|
1363
|
+
Start of the recovery time window (inclusive). All failed messages from this time onward will be retried.
|
|
1376
1364
|
|
|
1377
1365
|
until : typing.Optional[dt.datetime]
|
|
1366
|
+
End of the recovery time window (exclusive). If not specified, recovers all failed messages up to now.
|
|
1378
1367
|
|
|
1379
1368
|
request_options : typing.Optional[RequestOptions]
|
|
1380
1369
|
Request-specific configuration.
|
|
1381
1370
|
|
|
1382
1371
|
Returns
|
|
1383
1372
|
-------
|
|
1384
|
-
AsyncHttpResponse[
|
|
1385
|
-
|
|
1373
|
+
AsyncHttpResponse[RecoveryTask]
|
|
1374
|
+
Recovery task information
|
|
1386
1375
|
"""
|
|
1387
1376
|
_response = await self._client_wrapper.httpx_client.request(
|
|
1388
1377
|
f"events/subscriptions/{jsonable_encoder(subscription_id)}/recover",
|
|
@@ -1400,20 +1389,42 @@ class AsyncRawEventsClient:
|
|
|
1400
1389
|
try:
|
|
1401
1390
|
if 200 <= _response.status_code < 300:
|
|
1402
1391
|
_data = typing.cast(
|
|
1403
|
-
|
|
1392
|
+
RecoveryTask,
|
|
1404
1393
|
parse_obj_as(
|
|
1405
|
-
type_=
|
|
1394
|
+
type_=RecoveryTask, # type: ignore
|
|
1406
1395
|
object_=_response.json(),
|
|
1407
1396
|
),
|
|
1408
1397
|
)
|
|
1409
1398
|
return AsyncHttpResponse(response=_response, data=_data)
|
|
1399
|
+
if _response.status_code == 404:
|
|
1400
|
+
raise NotFoundError(
|
|
1401
|
+
headers=dict(_response.headers),
|
|
1402
|
+
body=typing.cast(
|
|
1403
|
+
NotFoundErrorResponse,
|
|
1404
|
+
parse_obj_as(
|
|
1405
|
+
type_=NotFoundErrorResponse, # type: ignore
|
|
1406
|
+
object_=_response.json(),
|
|
1407
|
+
),
|
|
1408
|
+
),
|
|
1409
|
+
)
|
|
1410
1410
|
if _response.status_code == 422:
|
|
1411
1411
|
raise UnprocessableEntityError(
|
|
1412
1412
|
headers=dict(_response.headers),
|
|
1413
1413
|
body=typing.cast(
|
|
1414
|
-
|
|
1414
|
+
typing.Optional[typing.Any],
|
|
1415
|
+
parse_obj_as(
|
|
1416
|
+
type_=typing.Optional[typing.Any], # type: ignore
|
|
1417
|
+
object_=_response.json(),
|
|
1418
|
+
),
|
|
1419
|
+
),
|
|
1420
|
+
)
|
|
1421
|
+
if _response.status_code == 429:
|
|
1422
|
+
raise TooManyRequestsError(
|
|
1423
|
+
headers=dict(_response.headers),
|
|
1424
|
+
body=typing.cast(
|
|
1425
|
+
RateLimitErrorResponse,
|
|
1415
1426
|
parse_obj_as(
|
|
1416
|
-
type_=
|
|
1427
|
+
type_=RateLimitErrorResponse, # type: ignore
|
|
1417
1428
|
object_=_response.json(),
|
|
1418
1429
|
),
|
|
1419
1430
|
),
|