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,202 @@
1
+ """Generated resource class for invitations — 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 InvitationsResource:
12
+ """Operations on invitations."""
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
+ *,
24
+ timeout: float | None = None,
25
+ headers: dict[str, str] | None = None,
26
+ ) -> Page[dict[str, Any]]:
27
+ """List Invitations"""
28
+ query: dict[str, Any] = {}
29
+ if limit is not None:
30
+ query["limit"] = limit
31
+ if cursor is not None:
32
+ query["cursor"] = cursor
33
+ if status is not None:
34
+ query["status"] = status
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
+ status: str | None = None,
54
+ *,
55
+ timeout: float | None = None,
56
+ headers: dict[str, str] | None = None,
57
+ ) -> AsyncIterator[dict[str, Any]]:
58
+ """Auto-paginating iterator over all invitations."""
59
+ async def _fetch(cursor: str | None = None) -> Page[dict[str, Any]]:
60
+ return await self.list(
61
+ limit=limit,
62
+ status=status,
63
+ cursor=cursor,
64
+ timeout=timeout,
65
+ headers=headers,
66
+ )
67
+ async for item in auto_paginate(_fetch):
68
+ yield item
69
+
70
+ async def create(
71
+ self,
72
+ body: dict[str, Any],
73
+ *,
74
+ idempotency_key: str | None = None,
75
+ timeout: float | None = None,
76
+ headers: dict[str, str] | None = None,
77
+ ) -> dict[str, Any]:
78
+ """Create Invitation"""
79
+ req_headers: dict[str, str] = {}
80
+ if headers:
81
+ req_headers.update(headers)
82
+ if idempotency_key:
83
+ req_headers["idempotency-key"] = idempotency_key
84
+ resp = await self._client.request(
85
+ "POST",
86
+ self._base_path,
87
+ body=body,
88
+ timeout=timeout,
89
+ headers=req_headers or None,
90
+ )
91
+ data = resp.data
92
+ if resp.etag and isinstance(data, dict):
93
+ data["_etag"] = resp.etag
94
+ return data
95
+
96
+ async def get(
97
+ self,
98
+ org_id: str,
99
+ invitation_id: str,
100
+ *,
101
+ timeout: float | None = None,
102
+ headers: dict[str, str] | None = None,
103
+ ) -> dict[str, Any]:
104
+ """Get Invitation"""
105
+ path = f"{self._base_path}/{org_id}/{invitation_id}"
106
+ resp = await self._client.request("GET", path, timeout=timeout, headers=headers)
107
+ data = resp.data
108
+ if resp.etag and isinstance(data, dict):
109
+ data["_etag"] = resp.etag
110
+ return data
111
+
112
+ async def update(
113
+ self,
114
+ org_id: str,
115
+ invitation_id: str,
116
+ body: dict[str, Any],
117
+ *,
118
+ if_match: str | None = None,
119
+ idempotency_key: str | None = None,
120
+ timeout: float | None = None,
121
+ headers: dict[str, str] | None = None,
122
+ ) -> dict[str, Any]:
123
+ """Update Invitation"""
124
+ path = f"{self._base_path}/{org_id}/{invitation_id}"
125
+ req_headers: dict[str, str] = {}
126
+ if headers:
127
+ req_headers.update(headers)
128
+ if if_match:
129
+ req_headers["if-match"] = if_match
130
+ if idempotency_key:
131
+ req_headers["idempotency-key"] = idempotency_key
132
+ resp = await self._client.request(
133
+ "PATCH",
134
+ path,
135
+ body=body,
136
+ timeout=timeout,
137
+ headers=req_headers or None,
138
+ )
139
+ data = resp.data
140
+ if resp.etag and isinstance(data, dict):
141
+ data["_etag"] = resp.etag
142
+ return data
143
+
144
+ async def resend(
145
+ self,
146
+ invitation_id: str,
147
+ *,
148
+ if_match: str | None = None,
149
+ idempotency_key: str | None = None,
150
+ timeout: float | None = None,
151
+ headers: dict[str, str] | None = None,
152
+ ) -> Any:
153
+ """Resend Invitation"""
154
+ _validate_path_segment(invitation_id, "invitation_id")
155
+ path = f"{self._base_path}/{invitation_id}/resend"
156
+ req_headers: dict[str, str] = {}
157
+ if headers:
158
+ req_headers.update(headers)
159
+ if if_match:
160
+ req_headers["if-match"] = if_match
161
+ if idempotency_key:
162
+ req_headers["idempotency-key"] = idempotency_key
163
+ resp = await self._client.request(
164
+ "POST",
165
+ path,
166
+ timeout=timeout,
167
+ headers=req_headers or None,
168
+ )
169
+ data = resp.data
170
+ if resp.etag and isinstance(data, dict):
171
+ data["_etag"] = resp.etag
172
+ return data
173
+
174
+ async def revoke(
175
+ self,
176
+ invitation_id: str,
177
+ *,
178
+ if_match: str | None = None,
179
+ idempotency_key: str | None = None,
180
+ timeout: float | None = None,
181
+ headers: dict[str, str] | None = None,
182
+ ) -> Any:
183
+ """Revoke Invitation"""
184
+ _validate_path_segment(invitation_id, "invitation_id")
185
+ path = f"{self._base_path}/{invitation_id}/revoke"
186
+ req_headers: dict[str, str] = {}
187
+ if headers:
188
+ req_headers.update(headers)
189
+ if if_match:
190
+ req_headers["if-match"] = if_match
191
+ if idempotency_key:
192
+ req_headers["idempotency-key"] = idempotency_key
193
+ resp = await self._client.request(
194
+ "POST",
195
+ path,
196
+ timeout=timeout,
197
+ headers=req_headers or None,
198
+ )
199
+ data = resp.data
200
+ if resp.etag and isinstance(data, dict):
201
+ data["_etag"] = resp.etag
202
+ return data
@@ -0,0 +1,157 @@
1
+ """Generated resource class for issuers — 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 IssuersResource:
12
+ """Operations on issuers."""
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
+ *,
23
+ timeout: float | None = None,
24
+ headers: dict[str, str] | None = None,
25
+ ) -> Page[dict[str, Any]]:
26
+ """List Issuers"""
27
+ query: dict[str, Any] = {}
28
+ if limit is not None:
29
+ query["limit"] = limit
30
+ if cursor is not None:
31
+ query["cursor"] = cursor
32
+ resp = await self._client.request(
33
+ "GET",
34
+ self._base_path,
35
+ query=query or None,
36
+ timeout=timeout,
37
+ headers=headers,
38
+ )
39
+ data = resp.data
40
+ items = data.get("data", []) if data else []
41
+ return Page(
42
+ data=items,
43
+ has_more=data.get("has_more", False) if data else False,
44
+ next_cursor=data.get("next_cursor") if data else None,
45
+ )
46
+
47
+ async def list_all(
48
+ self,
49
+ limit: int | None = None,
50
+ *,
51
+ timeout: float | None = None,
52
+ headers: dict[str, str] | None = None,
53
+ ) -> AsyncIterator[dict[str, Any]]:
54
+ """Auto-paginating iterator over all issuers."""
55
+ async def _fetch(cursor: str | None = None) -> Page[dict[str, Any]]:
56
+ return await self.list(
57
+ limit=limit,
58
+ cursor=cursor,
59
+ timeout=timeout,
60
+ headers=headers,
61
+ )
62
+ async for item in auto_paginate(_fetch):
63
+ yield item
64
+
65
+ async def create(
66
+ self,
67
+ body: dict[str, Any],
68
+ *,
69
+ idempotency_key: str | None = None,
70
+ timeout: float | None = None,
71
+ headers: dict[str, str] | None = None,
72
+ ) -> dict[str, Any]:
73
+ """Create Issuer"""
74
+ req_headers: dict[str, str] = {}
75
+ if headers:
76
+ req_headers.update(headers)
77
+ if idempotency_key:
78
+ req_headers["idempotency-key"] = idempotency_key
79
+ resp = await self._client.request(
80
+ "POST",
81
+ self._base_path,
82
+ body=body,
83
+ timeout=timeout,
84
+ headers=req_headers or None,
85
+ )
86
+ data = resp.data
87
+ if resp.etag and isinstance(data, dict):
88
+ data["_etag"] = resp.etag
89
+ return data
90
+
91
+ async def get(
92
+ self,
93
+ resource_id: str,
94
+ *,
95
+ timeout: float | None = None,
96
+ headers: dict[str, str] | None = None,
97
+ ) -> dict[str, Any]:
98
+ """Get Issuer"""
99
+ path = f"{self._base_path}/{resource_id}"
100
+ resp = await self._client.request("GET", path, timeout=timeout, headers=headers)
101
+ data = resp.data
102
+ if resp.etag and isinstance(data, dict):
103
+ data["_etag"] = resp.etag
104
+ return data
105
+
106
+ async def update(
107
+ self,
108
+ resource_id: str,
109
+ body: dict[str, Any],
110
+ *,
111
+ if_match: str | None = None,
112
+ idempotency_key: str | None = None,
113
+ timeout: float | None = None,
114
+ headers: dict[str, str] | None = None,
115
+ ) -> dict[str, Any]:
116
+ """Update Issuer"""
117
+ path = f"{self._base_path}/{resource_id}"
118
+ req_headers: dict[str, str] = {}
119
+ if headers:
120
+ req_headers.update(headers)
121
+ if if_match:
122
+ req_headers["if-match"] = if_match
123
+ if idempotency_key:
124
+ req_headers["idempotency-key"] = idempotency_key
125
+ resp = await self._client.request(
126
+ "PATCH",
127
+ path,
128
+ body=body,
129
+ timeout=timeout,
130
+ headers=req_headers or None,
131
+ )
132
+ data = resp.data
133
+ if resp.etag and isinstance(data, dict):
134
+ data["_etag"] = resp.etag
135
+ return data
136
+
137
+ async def delete(
138
+ self,
139
+ resource_id: str,
140
+ *,
141
+ if_match: str | None = None,
142
+ timeout: float | None = None,
143
+ headers: dict[str, str] | None = None,
144
+ ) -> None:
145
+ """Delete Issuer"""
146
+ path = f"{self._base_path}/{resource_id}"
147
+ req_headers: dict[str, str] = {}
148
+ if headers:
149
+ req_headers.update(headers)
150
+ if if_match:
151
+ req_headers["if-match"] = if_match
152
+ await self._client.request(
153
+ "DELETE",
154
+ path,
155
+ timeout=timeout,
156
+ headers=req_headers or None,
157
+ )
@@ -0,0 +1,154 @@
1
+ """Generated resource class for members — 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 MembersResource:
12
+ """Operations on members."""
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
+ scope: str | None = None,
24
+ *,
25
+ timeout: float | None = None,
26
+ headers: dict[str, str] | None = None,
27
+ ) -> Page[dict[str, Any]]:
28
+ """List Organization Members"""
29
+ query: dict[str, Any] = {}
30
+ if limit is not None:
31
+ query["limit"] = limit
32
+ if cursor is not None:
33
+ query["cursor"] = cursor
34
+ if status is not None:
35
+ query["status"] = status
36
+ if scope is not None:
37
+ query["scope"] = scope
38
+ resp = await self._client.request(
39
+ "GET",
40
+ self._base_path,
41
+ query=query or None,
42
+ timeout=timeout,
43
+ headers=headers,
44
+ )
45
+ data = resp.data
46
+ items = data.get("data", []) if data else []
47
+ return Page(
48
+ data=items,
49
+ has_more=data.get("has_more", False) if data else False,
50
+ next_cursor=data.get("next_cursor") if data else None,
51
+ )
52
+
53
+ async def list_all(
54
+ self,
55
+ limit: int | None = None,
56
+ status: str | None = None,
57
+ scope: str | None = None,
58
+ *,
59
+ timeout: float | None = None,
60
+ headers: dict[str, str] | None = None,
61
+ ) -> AsyncIterator[dict[str, Any]]:
62
+ """Auto-paginating iterator over all members."""
63
+ async def _fetch(cursor: str | None = None) -> Page[dict[str, Any]]:
64
+ return await self.list(
65
+ limit=limit,
66
+ status=status,
67
+ scope=scope,
68
+ cursor=cursor,
69
+ timeout=timeout,
70
+ headers=headers,
71
+ )
72
+ async for item in auto_paginate(_fetch):
73
+ yield item
74
+
75
+ async def create(
76
+ self,
77
+ body: dict[str, Any],
78
+ *,
79
+ idempotency_key: str | None = None,
80
+ timeout: float | None = None,
81
+ headers: dict[str, str] | None = None,
82
+ ) -> dict[str, Any]:
83
+ """Add Organization Member"""
84
+ req_headers: dict[str, str] = {}
85
+ if headers:
86
+ req_headers.update(headers)
87
+ if idempotency_key:
88
+ req_headers["idempotency-key"] = idempotency_key
89
+ resp = await self._client.request(
90
+ "POST",
91
+ self._base_path,
92
+ body=body,
93
+ timeout=timeout,
94
+ headers=req_headers or None,
95
+ )
96
+ data = resp.data
97
+ if resp.etag and isinstance(data, dict):
98
+ data["_etag"] = resp.etag
99
+ return data
100
+
101
+ async def update(
102
+ self,
103
+ org_id: str,
104
+ member_id: str,
105
+ body: dict[str, Any],
106
+ *,
107
+ if_match: str | None = None,
108
+ idempotency_key: str | None = None,
109
+ timeout: float | None = None,
110
+ headers: dict[str, str] | None = None,
111
+ ) -> dict[str, Any]:
112
+ """Update Organization Member"""
113
+ path = f"{self._base_path}/{org_id}/{member_id}"
114
+ req_headers: dict[str, str] = {}
115
+ if headers:
116
+ req_headers.update(headers)
117
+ if if_match:
118
+ req_headers["if-match"] = if_match
119
+ if idempotency_key:
120
+ req_headers["idempotency-key"] = idempotency_key
121
+ resp = await self._client.request(
122
+ "PATCH",
123
+ path,
124
+ body=body,
125
+ timeout=timeout,
126
+ headers=req_headers or None,
127
+ )
128
+ data = resp.data
129
+ if resp.etag and isinstance(data, dict):
130
+ data["_etag"] = resp.etag
131
+ return data
132
+
133
+ async def delete(
134
+ self,
135
+ org_id: str,
136
+ member_id: str,
137
+ *,
138
+ if_match: str | None = None,
139
+ timeout: float | None = None,
140
+ headers: dict[str, str] | None = None,
141
+ ) -> None:
142
+ """Remove Organization Member"""
143
+ path = f"{self._base_path}/{org_id}/{member_id}"
144
+ req_headers: dict[str, str] = {}
145
+ if headers:
146
+ req_headers.update(headers)
147
+ if if_match:
148
+ req_headers["if-match"] = if_match
149
+ await self._client.request(
150
+ "DELETE",
151
+ path,
152
+ timeout=timeout,
153
+ headers=req_headers or None,
154
+ )
@@ -0,0 +1,192 @@
1
+ """Generated resource class for notes — 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
+ CreateNoteInput,
12
+ UpdateNoteInput,
13
+ )
14
+
15
+
16
+ class NotesResource:
17
+ """Operations on notes."""
18
+
19
+ def __init__(self, client: HttpClient, base_path: str) -> None:
20
+ self._client = client
21
+ self._base_path = base_path
22
+
23
+ async def list(
24
+ self,
25
+ limit: int | None = None,
26
+ cursor: str | None = None,
27
+ subject_type: str | None = None,
28
+ subject_id: str | None = None,
29
+ issuer_id: str | None = None,
30
+ created_by: str | None = None,
31
+ pinned: bool | None = None,
32
+ mentions_user_id: str | None = None,
33
+ *,
34
+ timeout: float | None = None,
35
+ headers: dict[str, str] | None = None,
36
+ ) -> Page[Note]:
37
+ """List Notes"""
38
+ query: dict[str, Any] = {}
39
+ if limit is not None:
40
+ query["limit"] = limit
41
+ if cursor is not None:
42
+ query["cursor"] = cursor
43
+ if subject_type is not None:
44
+ query["subject_type"] = subject_type
45
+ if subject_id is not None:
46
+ query["subject_id"] = subject_id
47
+ if issuer_id is not None:
48
+ query["issuer_id"] = issuer_id
49
+ if created_by is not None:
50
+ query["created_by"] = created_by
51
+ if pinned is not None:
52
+ query["pinned"] = pinned
53
+ if mentions_user_id is not None:
54
+ query["mentions_user_id"] = mentions_user_id
55
+ resp = await self._client.request(
56
+ "GET",
57
+ self._base_path,
58
+ query=query or None,
59
+ timeout=timeout,
60
+ headers=headers,
61
+ )
62
+ data = resp.data
63
+ items = [Note(**item) for item in data.get("data", [])] if data else []
64
+ return Page(
65
+ data=items,
66
+ has_more=data.get("has_more", False) if data else False,
67
+ next_cursor=data.get("next_cursor") if data else None,
68
+ )
69
+
70
+ async def list_all(
71
+ self,
72
+ limit: int | None = None,
73
+ subject_type: str | None = None,
74
+ subject_id: str | None = None,
75
+ issuer_id: str | None = None,
76
+ created_by: str | None = None,
77
+ pinned: bool | None = None,
78
+ mentions_user_id: str | None = None,
79
+ *,
80
+ timeout: float | None = None,
81
+ headers: dict[str, str] | None = None,
82
+ ) -> AsyncIterator[Note]:
83
+ """Auto-paginating iterator over all notes."""
84
+ async def _fetch(cursor: str | None = None) -> Page[Note]:
85
+ return await self.list(
86
+ limit=limit,
87
+ subject_type=subject_type,
88
+ subject_id=subject_id,
89
+ issuer_id=issuer_id,
90
+ created_by=created_by,
91
+ pinned=pinned,
92
+ mentions_user_id=mentions_user_id,
93
+ cursor=cursor,
94
+ timeout=timeout,
95
+ headers=headers,
96
+ )
97
+ async for item in auto_paginate(_fetch):
98
+ yield item
99
+
100
+ async def create(
101
+ self,
102
+ body: dict[str, Any],
103
+ *,
104
+ idempotency_key: str | None = None,
105
+ timeout: float | None = None,
106
+ headers: dict[str, str] | None = None,
107
+ ) -> dict[str, Any]:
108
+ """Create Note"""
109
+ req_headers: dict[str, str] = {}
110
+ if headers:
111
+ req_headers.update(headers)
112
+ if idempotency_key:
113
+ req_headers["idempotency-key"] = idempotency_key
114
+ resp = await self._client.request(
115
+ "POST",
116
+ self._base_path,
117
+ body=body,
118
+ timeout=timeout,
119
+ headers=req_headers or None,
120
+ )
121
+ data = resp.data
122
+ if resp.etag and isinstance(data, dict):
123
+ data["_etag"] = resp.etag
124
+ return data
125
+
126
+ async def get(
127
+ self,
128
+ note_id: str,
129
+ *,
130
+ timeout: float | None = None,
131
+ headers: dict[str, str] | None = None,
132
+ ) -> dict[str, Any]:
133
+ """Get Note"""
134
+ path = f"{self._base_path}/{note_id}"
135
+ resp = await self._client.request("GET", path, timeout=timeout, headers=headers)
136
+ data = resp.data
137
+ if resp.etag and isinstance(data, dict):
138
+ data["_etag"] = resp.etag
139
+ return data
140
+
141
+ async def update(
142
+ self,
143
+ note_id: str,
144
+ body: dict[str, Any],
145
+ *,
146
+ if_match: str | None = None,
147
+ idempotency_key: str | None = None,
148
+ timeout: float | None = None,
149
+ headers: dict[str, str] | None = None,
150
+ ) -> dict[str, Any]:
151
+ """Update Note"""
152
+ path = f"{self._base_path}/{note_id}"
153
+ req_headers: dict[str, str] = {}
154
+ if headers:
155
+ req_headers.update(headers)
156
+ if if_match:
157
+ req_headers["if-match"] = if_match
158
+ if idempotency_key:
159
+ req_headers["idempotency-key"] = idempotency_key
160
+ resp = await self._client.request(
161
+ "PATCH",
162
+ path,
163
+ body=body,
164
+ timeout=timeout,
165
+ headers=req_headers or None,
166
+ )
167
+ data = resp.data
168
+ if resp.etag and isinstance(data, dict):
169
+ data["_etag"] = resp.etag
170
+ return data
171
+
172
+ async def delete(
173
+ self,
174
+ note_id: str,
175
+ *,
176
+ if_match: str | None = None,
177
+ timeout: float | None = None,
178
+ headers: dict[str, str] | None = None,
179
+ ) -> None:
180
+ """Delete Note"""
181
+ path = f"{self._base_path}/{note_id}"
182
+ req_headers: dict[str, str] = {}
183
+ if headers:
184
+ req_headers.update(headers)
185
+ if if_match:
186
+ req_headers["if-match"] = if_match
187
+ await self._client.request(
188
+ "DELETE",
189
+ path,
190
+ timeout=timeout,
191
+ headers=req_headers or None,
192
+ )