authpi-admin 0.3.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.
Files changed (40) hide show
  1. authpi_admin/__init__.py +55 -0
  2. authpi_admin/_version.py +5 -0
  3. authpi_admin/client.py +155 -0
  4. authpi_admin/errors.py +218 -0
  5. authpi_admin/generated/__init__.py +28 -0
  6. authpi_admin/generated/models.py +380 -0
  7. authpi_admin/generated/resources/__init__.py +0 -0
  8. authpi_admin/generated/resources/accounts.py +157 -0
  9. authpi_admin/generated/resources/agents.py +177 -0
  10. authpi_admin/generated/resources/api_keys.py +213 -0
  11. authpi_admin/generated/resources/approvals.py +109 -0
  12. authpi_admin/generated/resources/auth_methods.py +148 -0
  13. authpi_admin/generated/resources/clients.py +197 -0
  14. authpi_admin/generated/resources/deliveries.py +83 -0
  15. authpi_admin/generated/resources/domains.py +194 -0
  16. authpi_admin/generated/resources/events.py +111 -0
  17. authpi_admin/generated/resources/groups.py +160 -0
  18. authpi_admin/generated/resources/invitations.py +202 -0
  19. authpi_admin/generated/resources/issuers.py +157 -0
  20. authpi_admin/generated/resources/members.py +154 -0
  21. authpi_admin/generated/resources/notes.py +192 -0
  22. authpi_admin/generated/resources/organizations.py +244 -0
  23. authpi_admin/generated/resources/sessions.py +125 -0
  24. authpi_admin/generated/resources/tokens.py +94 -0
  25. authpi_admin/generated/resources/trusted_devices.py +102 -0
  26. authpi_admin/generated/resources/users.py +224 -0
  27. authpi_admin/generated/resources/verifiers.py +102 -0
  28. authpi_admin/generated/resources/webhooks.py +167 -0
  29. authpi_admin/generated/scopes/__init__.py +0 -0
  30. authpi_admin/generated/scopes/agent_scope.py +84 -0
  31. authpi_admin/generated/scopes/issuer_scope.py +160 -0
  32. authpi_admin/generated/scopes/user_scope.py +102 -0
  33. authpi_admin/generated/scopes/webhook_scope.py +84 -0
  34. authpi_admin/http_client.py +305 -0
  35. authpi_admin/pagination.py +41 -0
  36. authpi_admin/py.typed +0 -0
  37. authpi_admin/user_agent.py +21 -0
  38. authpi_admin-0.3.0.dist-info/METADATA +285 -0
  39. authpi_admin-0.3.0.dist-info/RECORD +40 -0
  40. authpi_admin-0.3.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,380 @@
1
+ """Generated Pydantic models — DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from enum import Enum
6
+ from typing import Any
7
+
8
+ from pydantic import BaseModel, ConfigDict, PrivateAttr
9
+
10
+ class NoteSubjectType(str, Enum):
11
+ """Type of resource the note is attached to"""
12
+ USER = "user"
13
+ ORG = "org"
14
+ ISSUER = "issuer"
15
+ CLIENT = "client"
16
+ AGENT = "agent"
17
+
18
+ class NoteRefType(str, Enum):
19
+ """Type of the referenced resource"""
20
+ USER = "user"
21
+ ORG = "org"
22
+ ISSUER = "issuer"
23
+ CLIENT = "client"
24
+ WEBHOOK = "webhook"
25
+ API_KEY = "api_key"
26
+
27
+ class Address(BaseModel):
28
+ model_config = ConfigDict(frozen=True)
29
+
30
+ _etag: str | None = PrivateAttr(default=None)
31
+
32
+ line1: str | None = None
33
+ line2: str | None = None
34
+ city: str | None = None
35
+ state: str | None = None
36
+ postal_code: str | None = None
37
+ country: str
38
+
39
+ class Metadata(BaseModel):
40
+ model_config = ConfigDict(frozen=True, extra="allow")
41
+
42
+ _etag: str | None = PrivateAttr(default=None)
43
+
44
+
45
+ class FieldError(BaseModel):
46
+ model_config = ConfigDict(frozen=True)
47
+
48
+ _etag: str | None = PrivateAttr(default=None)
49
+
50
+ field: str
51
+ code: str
52
+ message: str
53
+
54
+ class ApiError(BaseModel):
55
+ model_config = ConfigDict(frozen=True)
56
+
57
+ _etag: str | None = PrivateAttr(default=None)
58
+
59
+ error: str
60
+ error_description: str
61
+ reference: str | None = None
62
+ retryable: bool
63
+ retry_after: int | None = None
64
+ fields: list[FieldError] | None = None
65
+
66
+ class PreconditionFailedError(BaseModel):
67
+ model_config = ConfigDict(frozen=True)
68
+
69
+ _etag: str | None = PrivateAttr(default=None)
70
+
71
+ error: str
72
+ error_description: str
73
+ reference: str | None = None
74
+ retryable: bool
75
+ retry_after: int | None = None
76
+ fields: list[FieldError] | None = None
77
+ current_etag: str | None = None
78
+
79
+ class Client(BaseModel):
80
+ model_config = ConfigDict(frozen=True)
81
+
82
+ _etag: str | None = PrivateAttr(default=None)
83
+
84
+ id: str
85
+ issuer_id: str
86
+ status: str
87
+ type: str
88
+ confidential: bool
89
+ secret_rotated_at: int | None = None
90
+ name: str
91
+ description: str
92
+ logo_url: str
93
+ settings: dict[str, Any]
94
+ status_at: int | None = None
95
+ metadata: Metadata | None = None
96
+ created_at: int
97
+ updated_at: int | None = None
98
+
99
+ class Event(BaseModel):
100
+ model_config = ConfigDict(frozen=True)
101
+
102
+ _etag: str | None = PrivateAttr(default=None)
103
+
104
+ spec: str
105
+ id: str
106
+ trace: str | None = None
107
+ type: str
108
+ source: str
109
+ trigger: str | None = None
110
+ auth: dict[str, Any] | None = None
111
+ subject: dict[str, Any] | None = None
112
+ timestamp: float
113
+ data: dict[str, Any] | None = None
114
+
115
+ class WebhookListItem(BaseModel):
116
+ model_config = ConfigDict(frozen=True)
117
+
118
+ _etag: str | None = PrivateAttr(default=None)
119
+
120
+ id: str
121
+ account_id: str
122
+ status: str
123
+ name: str
124
+ description: str
125
+ url: str
126
+ auth_type: str
127
+ events: list[str]
128
+ status_at: int
129
+ created_at: int
130
+ updated_at: int
131
+
132
+ class CreateWebhookResponseAuth(BaseModel):
133
+ """Union type (oneOf)"""
134
+ model_config = ConfigDict(frozen=True, extra="allow")
135
+
136
+ _etag: str | None = PrivateAttr(default=None)
137
+
138
+
139
+ class CreateAuthInput(BaseModel):
140
+ """Union type (oneOf)"""
141
+ model_config = ConfigDict(frozen=True, extra="allow")
142
+
143
+ _etag: str | None = PrivateAttr(default=None)
144
+
145
+
146
+ class CreateWebhookInput(BaseModel):
147
+ model_config = ConfigDict(frozen=True)
148
+
149
+ _etag: str | None = PrivateAttr(default=None)
150
+
151
+ name: str
152
+ description: str | None = None
153
+ url: str
154
+ status: str | None = None
155
+ auth: CreateAuthInput
156
+ events: list[str]
157
+ subjects: list[dict[str, Any]] | None = None
158
+ retry: dict[str, Any] | None = None
159
+ circuit_breaker: dict[str, Any] | None = None
160
+ metadata: Metadata | None = None
161
+
162
+ class WebhookAuth(BaseModel):
163
+ """Union type (oneOf)"""
164
+ model_config = ConfigDict(frozen=True, extra="allow")
165
+
166
+ _etag: str | None = PrivateAttr(default=None)
167
+
168
+
169
+ class Webhook(BaseModel):
170
+ """The webhook configuration"""
171
+ model_config = ConfigDict(frozen=True)
172
+
173
+ _etag: str | None = PrivateAttr(default=None)
174
+
175
+ id: str
176
+ account_id: str
177
+ name: str
178
+ description: str | None = None
179
+ url: str
180
+ status: str | None = None
181
+ status_at: int | None = None
182
+ status_reason: str | None = None
183
+ status_by: str | None = None
184
+ auth: WebhookAuth
185
+ events: list[str]
186
+ subjects: list[dict[str, Any]] | None = None
187
+ retry: dict[str, Any] | None = None
188
+ circuit_breaker: dict[str, Any] | None = None
189
+ metadata: Metadata | None = None
190
+ created_at: int
191
+ updated_at: int | None = None
192
+
193
+ class UpdateWebhookResponseAuth(BaseModel):
194
+ """Union type (oneOf)"""
195
+ model_config = ConfigDict(frozen=True, extra="allow")
196
+
197
+ _etag: str | None = PrivateAttr(default=None)
198
+
199
+
200
+ class UpdateAuthInput(BaseModel):
201
+ """Union type (oneOf)"""
202
+ model_config = ConfigDict(frozen=True, extra="allow")
203
+
204
+ _etag: str | None = PrivateAttr(default=None)
205
+
206
+
207
+ class UpdateWebhook(BaseModel):
208
+ model_config = ConfigDict(frozen=True)
209
+
210
+ _etag: str | None = PrivateAttr(default=None)
211
+
212
+ name: str | None = None
213
+ description: str | None = None
214
+ url: str | None = None
215
+ status: str | None = None
216
+ status_reason: str | None = None
217
+ status_by: str | None = None
218
+ auth: UpdateAuthInput | None = None
219
+ events: list[str] | None = None
220
+ subjects: list[dict[str, Any]] | None = None
221
+ retry: dict[str, Any] | None = None
222
+ circuit_breaker: dict[str, Any] | None = None
223
+ metadata: Metadata | None = None
224
+
225
+ class ApiKey(BaseModel):
226
+ """The API key details"""
227
+ model_config = ConfigDict(frozen=True)
228
+
229
+ _etag: str | None = PrivateAttr(default=None)
230
+
231
+ issuer_id: str
232
+ type: str
233
+ name: str
234
+ description: str | None = None
235
+ tags: list[str] | None = None
236
+ restrictions: dict[str, Any]
237
+ status: str | None = None
238
+ status_at: int | None = None
239
+ status_reason: str | None = None
240
+ status_by: str | None = None
241
+ expires_at: int | None = None
242
+ metadata: Metadata | None = None
243
+ created_at: int
244
+ updated_at: int | None = None
245
+ id: str
246
+ org_id: str
247
+ secret: dict[str, Any]
248
+
249
+ class UpdateApiKey(BaseModel):
250
+ model_config = ConfigDict(frozen=True)
251
+
252
+ _etag: str | None = PrivateAttr(default=None)
253
+
254
+ status: str | None = None
255
+ status_reason: str | None = None
256
+ status_by: str | None = None
257
+ name: str | None = None
258
+ description: str | None = None
259
+ tags: list[str] | None = None
260
+ restrictions: dict[str, Any] | None = None
261
+ expires_at: int | None = None
262
+ metadata: Metadata | None = None
263
+
264
+ class PersonalToken(BaseModel):
265
+ """The personal token details"""
266
+ model_config = ConfigDict(frozen=True)
267
+
268
+ _etag: str | None = PrivateAttr(default=None)
269
+
270
+ issuer_id: str
271
+ type: str
272
+ name: str
273
+ description: str | None = None
274
+ tags: list[str] | None = None
275
+ restrictions: dict[str, Any]
276
+ status: str | None = None
277
+ status_at: int | None = None
278
+ status_reason: str | None = None
279
+ status_by: str | None = None
280
+ expires_at: int | None = None
281
+ metadata: Metadata | None = None
282
+ created_at: int
283
+ updated_at: int | None = None
284
+ id: str
285
+ user_id: str
286
+ audience: str | None = None
287
+ jti: str | None = None
288
+
289
+ class Session(BaseModel):
290
+ model_config = ConfigDict(frozen=True)
291
+
292
+ _etag: str | None = PrivateAttr(default=None)
293
+
294
+ id: str
295
+ user_id: str
296
+ issuer_id: str
297
+ type: str
298
+ status: str
299
+ status_at: int | None = None
300
+ status_reason: str | None = None
301
+ status_by: str | None = None
302
+ authentication: dict[str, Any] | None = None
303
+ client: dict[str, Any] | None = None
304
+ op_session_id: str | None = None
305
+ device: dict[str, Any] | None = None
306
+ location: dict[str, Any] | None = None
307
+ origin: str | None = None
308
+ ttl: int | None = None
309
+ idle_timeout: int | None = None
310
+ last_activity_at: int | None = None
311
+ access_token_issued_at: int | None = None
312
+ refresh_token_issued_at: int | None = None
313
+ refresh_count: int | None = None
314
+ secret: str | None = None
315
+ compromised: bool | None = None
316
+ compromised_at: int | None = None
317
+ compromised_reason: str | None = None
318
+ revoked_reason: str | None = None
319
+ metadata: Metadata | None = None
320
+ created_at: int
321
+ updated_at: int | None = None
322
+ expires_at: int | None = None
323
+ revoked_at: int | None = None
324
+
325
+ class NoteMention(BaseModel):
326
+ model_config = ConfigDict(frozen=True)
327
+
328
+ _etag: str | None = PrivateAttr(default=None)
329
+
330
+ mentioned_user_id: str
331
+ created_at: float
332
+
333
+ class NoteReference(BaseModel):
334
+ model_config = ConfigDict(frozen=True)
335
+
336
+ _etag: str | None = PrivateAttr(default=None)
337
+
338
+ ref_type: NoteRefType
339
+ ref_id: str
340
+ ref_issuer_id: str
341
+ created_at: float
342
+
343
+ class Note(BaseModel):
344
+ model_config = ConfigDict(frozen=True)
345
+
346
+ _etag: str | None = PrivateAttr(default=None)
347
+
348
+ id: str
349
+ account_id: str
350
+ issuer_id: str
351
+ subject_type: NoteSubjectType
352
+ subject_id: str
353
+ content: str
354
+ pinned: bool
355
+ created_by: str
356
+ updated_by: str
357
+ created_at: float
358
+ updated_at: float
359
+ mentions: list[NoteMention] | None = None
360
+ references: list[NoteReference] | None = None
361
+
362
+ class CreateNoteInput(BaseModel):
363
+ model_config = ConfigDict(frozen=True)
364
+
365
+ _etag: str | None = PrivateAttr(default=None)
366
+
367
+ subject_type: NoteSubjectType
368
+ subject_id: str
369
+ issuer_id: str | None = None
370
+ content: str
371
+ pinned: bool | None = None
372
+
373
+ class UpdateNoteInput(BaseModel):
374
+ model_config = ConfigDict(frozen=True)
375
+
376
+ _etag: str | None = PrivateAttr(default=None)
377
+
378
+ content: str | None = None
379
+ pinned: bool | None = None
380
+
File without changes
@@ -0,0 +1,157 @@
1
+ """Generated resource class for accounts — DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, AsyncIterator
6
+
7
+ from authpi_admin.http_client import HttpClient, validate_path_segment as _validate_path_segment
8
+ from authpi_admin.pagination import Page, auto_paginate
9
+ from authpi_admin.generated.models import (
10
+ Note,
11
+ )
12
+
13
+
14
+ class AccountsResource:
15
+ """Operations on accounts."""
16
+
17
+ def __init__(self, client: HttpClient, base_path: str) -> None:
18
+ self._client = client
19
+ self._base_path = base_path
20
+
21
+ async def list(
22
+ self,
23
+ limit: int | None = None,
24
+ cursor: str | None = None,
25
+ *,
26
+ timeout: float | None = None,
27
+ headers: dict[str, str] | None = None,
28
+ ) -> Page[dict[str, Any]]:
29
+ """List Accounts"""
30
+ query: dict[str, Any] = {}
31
+ if limit is not None:
32
+ query["limit"] = limit
33
+ if cursor is not None:
34
+ query["cursor"] = cursor
35
+ resp = await self._client.request(
36
+ "GET",
37
+ self._base_path,
38
+ query=query or None,
39
+ timeout=timeout,
40
+ headers=headers,
41
+ )
42
+ data = resp.data
43
+ items = data.get("data", []) if data else []
44
+ return Page(
45
+ data=items,
46
+ has_more=data.get("has_more", False) if data else False,
47
+ next_cursor=data.get("next_cursor") if data else None,
48
+ )
49
+
50
+ async def list_all(
51
+ self,
52
+ limit: int | None = None,
53
+ *,
54
+ timeout: float | None = None,
55
+ headers: dict[str, str] | None = None,
56
+ ) -> AsyncIterator[dict[str, Any]]:
57
+ """Auto-paginating iterator over all accounts."""
58
+ async def _fetch(cursor: str | None = None) -> Page[dict[str, Any]]:
59
+ return await self.list(
60
+ limit=limit,
61
+ cursor=cursor,
62
+ timeout=timeout,
63
+ headers=headers,
64
+ )
65
+ async for item in auto_paginate(_fetch):
66
+ yield item
67
+
68
+ async def get(
69
+ self,
70
+ resource_id: str,
71
+ *,
72
+ timeout: float | None = None,
73
+ headers: dict[str, str] | None = None,
74
+ ) -> dict[str, Any]:
75
+ """Get Account"""
76
+ path = f"{self._base_path}/{resource_id}"
77
+ resp = await self._client.request("GET", path, timeout=timeout, headers=headers)
78
+ data = resp.data
79
+ if resp.etag and isinstance(data, dict):
80
+ data["_etag"] = resp.etag
81
+ return data
82
+
83
+ async def update(
84
+ self,
85
+ resource_id: str,
86
+ body: dict[str, Any],
87
+ *,
88
+ if_match: str | None = None,
89
+ idempotency_key: str | None = None,
90
+ timeout: float | None = None,
91
+ headers: dict[str, str] | None = None,
92
+ ) -> dict[str, Any]:
93
+ """Update Account"""
94
+ path = f"{self._base_path}/{resource_id}"
95
+ req_headers: dict[str, str] = {}
96
+ if headers:
97
+ req_headers.update(headers)
98
+ if if_match:
99
+ req_headers["if-match"] = if_match
100
+ if idempotency_key:
101
+ req_headers["idempotency-key"] = idempotency_key
102
+ resp = await self._client.request(
103
+ "PATCH",
104
+ path,
105
+ body=body,
106
+ timeout=timeout,
107
+ headers=req_headers or None,
108
+ )
109
+ data = resp.data
110
+ if resp.etag and isinstance(data, dict):
111
+ data["_etag"] = resp.etag
112
+ return data
113
+
114
+ async def backlinks_notes(
115
+ self,
116
+ account_id: str,
117
+ *,
118
+ timeout: float | None = None,
119
+ headers: dict[str, str] | None = None,
120
+ ) -> Note:
121
+ """Get Note Backlinks"""
122
+ _validate_path_segment(account_id, "account_id")
123
+ path = f"{self._base_path}/{account_id}/notes/backlinks"
124
+ req_headers: dict[str, str] = {}
125
+ if headers:
126
+ req_headers.update(headers)
127
+ resp = await self._client.request(
128
+ "GET",
129
+ path,
130
+ timeout=timeout,
131
+ headers=req_headers or None,
132
+ )
133
+ return Note(**resp.data) if resp.data else resp.data
134
+
135
+ async def count_notes(
136
+ self,
137
+ account_id: str,
138
+ *,
139
+ timeout: float | None = None,
140
+ headers: dict[str, str] | None = None,
141
+ ) -> dict[str, Any]:
142
+ """Count Notes"""
143
+ _validate_path_segment(account_id, "account_id")
144
+ path = f"{self._base_path}/{account_id}/notes/count"
145
+ req_headers: dict[str, str] = {}
146
+ if headers:
147
+ req_headers.update(headers)
148
+ resp = await self._client.request(
149
+ "GET",
150
+ path,
151
+ timeout=timeout,
152
+ headers=req_headers or None,
153
+ )
154
+ data = resp.data
155
+ if resp.etag and isinstance(data, dict):
156
+ data["_etag"] = resp.etag
157
+ return data
@@ -0,0 +1,177 @@
1
+ """Generated resource class for agents — DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, AsyncIterator
6
+
7
+ from authpi_admin.http_client import HttpClient, validate_path_segment as _validate_path_segment
8
+ from authpi_admin.pagination import Page, auto_paginate
9
+
10
+
11
+ class AgentsResource:
12
+ """Operations on agents."""
13
+
14
+ def __init__(self, client: HttpClient, base_path: str) -> None:
15
+ self._client = client
16
+ self._base_path = base_path
17
+
18
+ async def list(
19
+ self,
20
+ limit: int | None = None,
21
+ cursor: str | None = None,
22
+ status: str | None = None,
23
+ model: str | None = None,
24
+ provider: str | None = None,
25
+ has_verifiers: str | None = None,
26
+ *,
27
+ timeout: float | None = None,
28
+ headers: dict[str, str] | None = None,
29
+ ) -> Page[dict[str, Any]]:
30
+ """List Agents"""
31
+ query: dict[str, Any] = {}
32
+ if limit is not None:
33
+ query["limit"] = limit
34
+ if cursor is not None:
35
+ query["cursor"] = cursor
36
+ if status is not None:
37
+ query["status"] = status
38
+ if model is not None:
39
+ query["model"] = model
40
+ if provider is not None:
41
+ query["provider"] = provider
42
+ if has_verifiers is not None:
43
+ query["has_verifiers"] = has_verifiers
44
+ resp = await self._client.request(
45
+ "GET",
46
+ self._base_path,
47
+ query=query or None,
48
+ timeout=timeout,
49
+ headers=headers,
50
+ )
51
+ data = resp.data
52
+ items = data.get("data", []) if data else []
53
+ return Page(
54
+ data=items,
55
+ has_more=data.get("has_more", False) if data else False,
56
+ next_cursor=data.get("next_cursor") if data else None,
57
+ )
58
+
59
+ async def list_all(
60
+ self,
61
+ limit: int | None = None,
62
+ status: str | None = None,
63
+ model: str | None = None,
64
+ provider: str | None = None,
65
+ has_verifiers: str | None = None,
66
+ *,
67
+ timeout: float | None = None,
68
+ headers: dict[str, str] | None = None,
69
+ ) -> AsyncIterator[dict[str, Any]]:
70
+ """Auto-paginating iterator over all agents."""
71
+ async def _fetch(cursor: str | None = None) -> Page[dict[str, Any]]:
72
+ return await self.list(
73
+ limit=limit,
74
+ status=status,
75
+ model=model,
76
+ provider=provider,
77
+ has_verifiers=has_verifiers,
78
+ cursor=cursor,
79
+ timeout=timeout,
80
+ headers=headers,
81
+ )
82
+ async for item in auto_paginate(_fetch):
83
+ yield item
84
+
85
+ async def create(
86
+ self,
87
+ body: dict[str, Any],
88
+ *,
89
+ idempotency_key: str | None = None,
90
+ timeout: float | None = None,
91
+ headers: dict[str, str] | None = None,
92
+ ) -> dict[str, Any]:
93
+ """Create Agent"""
94
+ req_headers: dict[str, str] = {}
95
+ if headers:
96
+ req_headers.update(headers)
97
+ if idempotency_key:
98
+ req_headers["idempotency-key"] = idempotency_key
99
+ resp = await self._client.request(
100
+ "POST",
101
+ self._base_path,
102
+ body=body,
103
+ timeout=timeout,
104
+ headers=req_headers or None,
105
+ )
106
+ data = resp.data
107
+ if resp.etag and isinstance(data, dict):
108
+ data["_etag"] = resp.etag
109
+ return data
110
+
111
+ async def get(
112
+ self,
113
+ resource_id: str,
114
+ *,
115
+ timeout: float | None = None,
116
+ headers: dict[str, str] | None = None,
117
+ ) -> dict[str, Any]:
118
+ """Get Agent"""
119
+ path = f"{self._base_path}/{resource_id}"
120
+ resp = await self._client.request("GET", path, timeout=timeout, headers=headers)
121
+ data = resp.data
122
+ if resp.etag and isinstance(data, dict):
123
+ data["_etag"] = resp.etag
124
+ return data
125
+
126
+ async def update(
127
+ self,
128
+ resource_id: str,
129
+ body: dict[str, Any],
130
+ *,
131
+ if_match: str | None = None,
132
+ idempotency_key: str | None = None,
133
+ timeout: float | None = None,
134
+ headers: dict[str, str] | None = None,
135
+ ) -> dict[str, Any]:
136
+ """Update Agent"""
137
+ path = f"{self._base_path}/{resource_id}"
138
+ req_headers: dict[str, str] = {}
139
+ if headers:
140
+ req_headers.update(headers)
141
+ if if_match:
142
+ req_headers["if-match"] = if_match
143
+ if idempotency_key:
144
+ req_headers["idempotency-key"] = idempotency_key
145
+ resp = await self._client.request(
146
+ "PATCH",
147
+ path,
148
+ body=body,
149
+ timeout=timeout,
150
+ headers=req_headers or None,
151
+ )
152
+ data = resp.data
153
+ if resp.etag and isinstance(data, dict):
154
+ data["_etag"] = resp.etag
155
+ return data
156
+
157
+ async def delete(
158
+ self,
159
+ resource_id: str,
160
+ *,
161
+ if_match: str | None = None,
162
+ timeout: float | None = None,
163
+ headers: dict[str, str] | None = None,
164
+ ) -> None:
165
+ """Delete Agent"""
166
+ path = f"{self._base_path}/{resource_id}"
167
+ req_headers: dict[str, str] = {}
168
+ if headers:
169
+ req_headers.update(headers)
170
+ if if_match:
171
+ req_headers["if-match"] = if_match
172
+ await self._client.request(
173
+ "DELETE",
174
+ path,
175
+ timeout=timeout,
176
+ headers=req_headers or None,
177
+ )