daknode 0.1.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 (84) hide show
  1. daknode/__init__.py +8 -0
  2. daknode/api/__init__.py +1 -0
  3. daknode/api/block_rules/__init__.py +1 -0
  4. daknode/api/block_rules/create_block_rule.py +211 -0
  5. daknode/api/block_rules/create_inbox_block_rule.py +225 -0
  6. daknode/api/block_rules/delete_block_rule.py +192 -0
  7. daknode/api/block_rules/list_block_rules.py +214 -0
  8. daknode/api/block_rules/list_inbox_block_rules.py +228 -0
  9. daknode/api/consent/__init__.py +1 -0
  10. daknode/api/consent/create_consent.py +203 -0
  11. daknode/api/consent/revoke.py +195 -0
  12. daknode/api/control_plane/__init__.py +1 -0
  13. daknode/api/control_plane/close_workspace.py +184 -0
  14. daknode/api/control_plane/create_workspace.py +211 -0
  15. daknode/api/control_plane/list_workspaces.py +155 -0
  16. daknode/api/control_plane/read_workspace.py +176 -0
  17. daknode/api/control_plane/update_workspace.py +197 -0
  18. daknode/api/dead_letters/__init__.py +1 -0
  19. daknode/api/dead_letters/list_dead_letters.py +198 -0
  20. daknode/api/dead_letters/replay_dead_letter.py +216 -0
  21. daknode/api/inboxes/__init__.py +1 -0
  22. daknode/api/inboxes/create_inbox.py +183 -0
  23. daknode/api/inboxes/register_webhook.py +225 -0
  24. daknode/api/inboxes/rotate_webhook_secret.py +224 -0
  25. daknode/api/messages/__init__.py +1 -0
  26. daknode/api/messages/get_message.py +176 -0
  27. daknode/api/messages/get_thread.py +184 -0
  28. daknode/api/messages/list_messages.py +228 -0
  29. daknode/api/messages/list_threads.py +228 -0
  30. daknode/api/privacy/__init__.py +1 -0
  31. daknode/api/privacy/create_erasure_request.py +227 -0
  32. daknode/api/privacy/read_erasure_request.py +200 -0
  33. daknode/api/public/__init__.py +1 -0
  34. daknode/api/public/agent_signup.py +191 -0
  35. daknode/api/public/agent_verify.py +191 -0
  36. daknode/api/search/__init__.py +1 -0
  37. daknode/api/search/search.py +207 -0
  38. daknode/api/send/__init__.py +1 -0
  39. daknode/api/send/send.py +254 -0
  40. daknode/client.py +270 -0
  41. daknode/errors.py +14 -0
  42. daknode/models/__init__.py +79 -0
  43. daknode/models/block_rule_create.py +104 -0
  44. daknode/models/block_rule_out.py +160 -0
  45. daknode/models/block_rule_page.py +116 -0
  46. daknode/models/consent_request.py +104 -0
  47. daknode/models/consent_response.py +105 -0
  48. daknode/models/create_erasure_request_response_create_erasure_request.py +63 -0
  49. daknode/models/create_in.py +119 -0
  50. daknode/models/dead_letter_response.py +205 -0
  51. daknode/models/erasure_request_body.py +60 -0
  52. daknode/models/http_validation_error.py +97 -0
  53. daknode/models/inbox_create_request.py +120 -0
  54. daknode/models/inbox_response.py +148 -0
  55. daknode/models/message_out.py +309 -0
  56. daknode/models/message_page.py +116 -0
  57. daknode/models/read_erasure_request_response_read_erasure_request.py +63 -0
  58. daknode/models/replay_response.py +113 -0
  59. daknode/models/revoke_request.py +74 -0
  60. daknode/models/revoke_response_revoke.py +63 -0
  61. daknode/models/search_match.py +170 -0
  62. daknode/models/search_request.py +107 -0
  63. daknode/models/search_response.py +124 -0
  64. daknode/models/send_request.py +162 -0
  65. daknode/models/send_response_send.py +63 -0
  66. daknode/models/signup_in.py +63 -0
  67. daknode/models/signup_out.py +102 -0
  68. daknode/models/thread_detail_out.py +223 -0
  69. daknode/models/thread_out.py +163 -0
  70. daknode/models/thread_page.py +116 -0
  71. daknode/models/timeline_item_out.py +280 -0
  72. daknode/models/update_in.py +111 -0
  73. daknode/models/validation_error.py +141 -0
  74. daknode/models/validation_error_context.py +63 -0
  75. daknode/models/verify_in.py +67 -0
  76. daknode/models/verify_out.py +74 -0
  77. daknode/models/webhook_register_request.py +74 -0
  78. daknode/models/workspace_list_out.py +92 -0
  79. daknode/models/workspace_out.py +147 -0
  80. daknode/py.typed +1 -0
  81. daknode/types.py +53 -0
  82. daknode-0.1.0.dist-info/METADATA +143 -0
  83. daknode-0.1.0.dist-info/RECORD +84 -0
  84. daknode-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,191 @@
1
+ from http import HTTPStatus
2
+ from typing import Any, Optional, Union, cast
3
+
4
+ import httpx
5
+
6
+ from ...client import AuthenticatedClient, Client
7
+ from ...types import Response, UNSET
8
+ from ... import errors
9
+
10
+ from ...models.http_validation_error import HTTPValidationError
11
+ from ...models.verify_in import VerifyIn
12
+ from ...models.verify_out import VerifyOut
13
+ from typing import cast
14
+
15
+
16
+
17
+ def _get_kwargs(
18
+ *,
19
+ body: VerifyIn,
20
+
21
+ ) -> dict[str, Any]:
22
+ headers: dict[str, Any] = {}
23
+
24
+
25
+
26
+
27
+
28
+
29
+ _kwargs: dict[str, Any] = {
30
+ "method": "post",
31
+ "url": "/v1/public/agents/verify",
32
+ }
33
+
34
+ _kwargs["json"] = body.to_dict()
35
+
36
+
37
+ headers["Content-Type"] = "application/json"
38
+
39
+ _kwargs["headers"] = headers
40
+ return _kwargs
41
+
42
+
43
+ def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Union[HTTPValidationError, VerifyOut]]:
44
+ if response.status_code == 200:
45
+ response_200 = VerifyOut.from_dict(response.json())
46
+
47
+
48
+
49
+ return response_200
50
+ if response.status_code == 422:
51
+ response_422 = HTTPValidationError.from_dict(response.json())
52
+
53
+
54
+
55
+ return response_422
56
+ if client.raise_on_unexpected_status:
57
+ raise errors.UnexpectedStatus(response.status_code, response.content)
58
+ else:
59
+ return None
60
+
61
+
62
+ def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[Union[HTTPValidationError, VerifyOut]]:
63
+ return Response(
64
+ status_code=HTTPStatus(response.status_code),
65
+ content=response.content,
66
+ headers=response.headers,
67
+ parsed=_parse_response(client=client, response=response),
68
+ )
69
+
70
+
71
+ def sync_detailed(
72
+ *,
73
+ client: Union[AuthenticatedClient, Client],
74
+ body: VerifyIn,
75
+
76
+ ) -> Response[Union[HTTPValidationError, VerifyOut]]:
77
+ """ Agent Verify
78
+
79
+ Check a code. Every failure answers identically.
80
+
81
+ Args:
82
+ body (VerifyIn):
83
+
84
+ Raises:
85
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
86
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
87
+
88
+ Returns:
89
+ Response[Union[HTTPValidationError, VerifyOut]]
90
+ """
91
+
92
+
93
+ kwargs = _get_kwargs(
94
+ body=body,
95
+
96
+ )
97
+
98
+ response = client.get_httpx_client().request(
99
+ **kwargs,
100
+ )
101
+
102
+ return _build_response(client=client, response=response)
103
+
104
+ def sync(
105
+ *,
106
+ client: Union[AuthenticatedClient, Client],
107
+ body: VerifyIn,
108
+
109
+ ) -> Optional[Union[HTTPValidationError, VerifyOut]]:
110
+ """ Agent Verify
111
+
112
+ Check a code. Every failure answers identically.
113
+
114
+ Args:
115
+ body (VerifyIn):
116
+
117
+ Raises:
118
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
119
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
120
+
121
+ Returns:
122
+ Union[HTTPValidationError, VerifyOut]
123
+ """
124
+
125
+
126
+ return sync_detailed(
127
+ client=client,
128
+ body=body,
129
+
130
+ ).parsed
131
+
132
+ async def asyncio_detailed(
133
+ *,
134
+ client: Union[AuthenticatedClient, Client],
135
+ body: VerifyIn,
136
+
137
+ ) -> Response[Union[HTTPValidationError, VerifyOut]]:
138
+ """ Agent Verify
139
+
140
+ Check a code. Every failure answers identically.
141
+
142
+ Args:
143
+ body (VerifyIn):
144
+
145
+ Raises:
146
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
147
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
148
+
149
+ Returns:
150
+ Response[Union[HTTPValidationError, VerifyOut]]
151
+ """
152
+
153
+
154
+ kwargs = _get_kwargs(
155
+ body=body,
156
+
157
+ )
158
+
159
+ response = await client.get_async_httpx_client().request(
160
+ **kwargs
161
+ )
162
+
163
+ return _build_response(client=client, response=response)
164
+
165
+ async def asyncio(
166
+ *,
167
+ client: Union[AuthenticatedClient, Client],
168
+ body: VerifyIn,
169
+
170
+ ) -> Optional[Union[HTTPValidationError, VerifyOut]]:
171
+ """ Agent Verify
172
+
173
+ Check a code. Every failure answers identically.
174
+
175
+ Args:
176
+ body (VerifyIn):
177
+
178
+ Raises:
179
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
180
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
181
+
182
+ Returns:
183
+ Union[HTTPValidationError, VerifyOut]
184
+ """
185
+
186
+
187
+ return (await asyncio_detailed(
188
+ client=client,
189
+ body=body,
190
+
191
+ )).parsed
@@ -0,0 +1 @@
1
+ """ Contains endpoint functions for accessing the API """
@@ -0,0 +1,207 @@
1
+ from http import HTTPStatus
2
+ from typing import Any, Optional, Union, cast
3
+
4
+ import httpx
5
+
6
+ from ...client import AuthenticatedClient, Client
7
+ from ...types import Response, UNSET
8
+ from ... import errors
9
+
10
+ from ...models.http_validation_error import HTTPValidationError
11
+ from ...models.search_request import SearchRequest
12
+ from ...models.search_response import SearchResponse
13
+ from typing import cast
14
+
15
+
16
+
17
+ def _get_kwargs(
18
+ *,
19
+ body: SearchRequest,
20
+
21
+ ) -> dict[str, Any]:
22
+ headers: dict[str, Any] = {}
23
+
24
+
25
+
26
+
27
+
28
+
29
+ _kwargs: dict[str, Any] = {
30
+ "method": "post",
31
+ "url": "/v1/search",
32
+ }
33
+
34
+ _kwargs["json"] = body.to_dict()
35
+
36
+
37
+ headers["Content-Type"] = "application/json"
38
+
39
+ _kwargs["headers"] = headers
40
+ return _kwargs
41
+
42
+
43
+ def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Union[HTTPValidationError, SearchResponse]]:
44
+ if response.status_code == 200:
45
+ response_200 = SearchResponse.from_dict(response.json())
46
+
47
+
48
+
49
+ return response_200
50
+ if response.status_code == 422:
51
+ response_422 = HTTPValidationError.from_dict(response.json())
52
+
53
+
54
+
55
+ return response_422
56
+ if client.raise_on_unexpected_status:
57
+ raise errors.UnexpectedStatus(response.status_code, response.content)
58
+ else:
59
+ return None
60
+
61
+
62
+ def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[Union[HTTPValidationError, SearchResponse]]:
63
+ return Response(
64
+ status_code=HTTPStatus(response.status_code),
65
+ content=response.content,
66
+ headers=response.headers,
67
+ parsed=_parse_response(client=client, response=response),
68
+ )
69
+
70
+
71
+ def sync_detailed(
72
+ *,
73
+ client: AuthenticatedClient,
74
+ body: SearchRequest,
75
+
76
+ ) -> Response[Union[HTTPValidationError, SearchResponse]]:
77
+ """ Search
78
+
79
+ Nearest neighbours within the caller's own mail.
80
+
81
+ Ordering is by similarity and is **not stable between calls** — an
82
+ approximate index re-ranks as content changes. There is no cursor; see
83
+ spec §5 for why keyset pagination does not apply.
84
+
85
+ Args:
86
+ body (SearchRequest):
87
+
88
+ Raises:
89
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
90
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
91
+
92
+ Returns:
93
+ Response[Union[HTTPValidationError, SearchResponse]]
94
+ """
95
+
96
+
97
+ kwargs = _get_kwargs(
98
+ body=body,
99
+
100
+ )
101
+
102
+ response = client.get_httpx_client().request(
103
+ **kwargs,
104
+ )
105
+
106
+ return _build_response(client=client, response=response)
107
+
108
+ def sync(
109
+ *,
110
+ client: AuthenticatedClient,
111
+ body: SearchRequest,
112
+
113
+ ) -> Optional[Union[HTTPValidationError, SearchResponse]]:
114
+ """ Search
115
+
116
+ Nearest neighbours within the caller's own mail.
117
+
118
+ Ordering is by similarity and is **not stable between calls** — an
119
+ approximate index re-ranks as content changes. There is no cursor; see
120
+ spec §5 for why keyset pagination does not apply.
121
+
122
+ Args:
123
+ body (SearchRequest):
124
+
125
+ Raises:
126
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
127
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
128
+
129
+ Returns:
130
+ Union[HTTPValidationError, SearchResponse]
131
+ """
132
+
133
+
134
+ return sync_detailed(
135
+ client=client,
136
+ body=body,
137
+
138
+ ).parsed
139
+
140
+ async def asyncio_detailed(
141
+ *,
142
+ client: AuthenticatedClient,
143
+ body: SearchRequest,
144
+
145
+ ) -> Response[Union[HTTPValidationError, SearchResponse]]:
146
+ """ Search
147
+
148
+ Nearest neighbours within the caller's own mail.
149
+
150
+ Ordering is by similarity and is **not stable between calls** — an
151
+ approximate index re-ranks as content changes. There is no cursor; see
152
+ spec §5 for why keyset pagination does not apply.
153
+
154
+ Args:
155
+ body (SearchRequest):
156
+
157
+ Raises:
158
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
159
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
160
+
161
+ Returns:
162
+ Response[Union[HTTPValidationError, SearchResponse]]
163
+ """
164
+
165
+
166
+ kwargs = _get_kwargs(
167
+ body=body,
168
+
169
+ )
170
+
171
+ response = await client.get_async_httpx_client().request(
172
+ **kwargs
173
+ )
174
+
175
+ return _build_response(client=client, response=response)
176
+
177
+ async def asyncio(
178
+ *,
179
+ client: AuthenticatedClient,
180
+ body: SearchRequest,
181
+
182
+ ) -> Optional[Union[HTTPValidationError, SearchResponse]]:
183
+ """ Search
184
+
185
+ Nearest neighbours within the caller's own mail.
186
+
187
+ Ordering is by similarity and is **not stable between calls** — an
188
+ approximate index re-ranks as content changes. There is no cursor; see
189
+ spec §5 for why keyset pagination does not apply.
190
+
191
+ Args:
192
+ body (SearchRequest):
193
+
194
+ Raises:
195
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
196
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
197
+
198
+ Returns:
199
+ Union[HTTPValidationError, SearchResponse]
200
+ """
201
+
202
+
203
+ return (await asyncio_detailed(
204
+ client=client,
205
+ body=body,
206
+
207
+ )).parsed
@@ -0,0 +1 @@
1
+ """ Contains endpoint functions for accessing the API """
@@ -0,0 +1,254 @@
1
+ from http import HTTPStatus
2
+ from typing import Any, Optional, Union, cast
3
+
4
+ import httpx
5
+
6
+ from ...client import AuthenticatedClient, Client
7
+ from ...types import Response, UNSET
8
+ from ... import errors
9
+
10
+ from ...models.http_validation_error import HTTPValidationError
11
+ from ...models.send_request import SendRequest
12
+ from ...models.send_response_send import SendResponseSend
13
+ from ...types import UNSET, Unset
14
+ from typing import cast
15
+ from typing import cast, Union
16
+ from typing import Union
17
+
18
+
19
+
20
+ def _get_kwargs(
21
+ *,
22
+ body: SendRequest,
23
+ idempotency_key: Union[None, Unset, str] = UNSET,
24
+
25
+ ) -> dict[str, Any]:
26
+ headers: dict[str, Any] = {}
27
+ if not isinstance(idempotency_key, Unset):
28
+ headers["Idempotency-Key"] = idempotency_key
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+ _kwargs: dict[str, Any] = {
37
+ "method": "post",
38
+ "url": "/v1/send",
39
+ }
40
+
41
+ _kwargs["json"] = body.to_dict()
42
+
43
+
44
+ headers["Content-Type"] = "application/json"
45
+
46
+ _kwargs["headers"] = headers
47
+ return _kwargs
48
+
49
+
50
+ def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Union[HTTPValidationError, SendResponseSend]]:
51
+ if response.status_code == 200:
52
+ response_200 = SendResponseSend.from_dict(response.json())
53
+
54
+
55
+
56
+ return response_200
57
+ if response.status_code == 422:
58
+ response_422 = HTTPValidationError.from_dict(response.json())
59
+
60
+
61
+
62
+ return response_422
63
+ if client.raise_on_unexpected_status:
64
+ raise errors.UnexpectedStatus(response.status_code, response.content)
65
+ else:
66
+ return None
67
+
68
+
69
+ def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[Union[HTTPValidationError, SendResponseSend]]:
70
+ return Response(
71
+ status_code=HTTPStatus(response.status_code),
72
+ content=response.content,
73
+ headers=response.headers,
74
+ parsed=_parse_response(client=client, response=response),
75
+ )
76
+
77
+
78
+ def sync_detailed(
79
+ *,
80
+ client: AuthenticatedClient,
81
+ body: SendRequest,
82
+ idempotency_key: Union[None, Unset, str] = UNSET,
83
+
84
+ ) -> Response[Union[HTTPValidationError, SendResponseSend]]:
85
+ """ Send
86
+
87
+ Accept one outbound message.
88
+
89
+ The header is **mandatory**. An endpoint that sends email on a retryable
90
+ verb without one has no way to tell a retry from a second request, and the
91
+ caller cannot add idempotency afterwards.
92
+
93
+ Args:
94
+ idempotency_key (Union[None, Unset, str]):
95
+ body (SendRequest): `extra="forbid"` is load-bearing.
96
+
97
+ There is no `from`, `sender` or `return_path` field: the From identity comes
98
+ from the tenant's inbox record. Forbidding extras makes a caller who tries to
99
+ set one get a `422` instead of a silent `202` — being ignored is worse,
100
+ because the integrator believes they chose a sender and nothing says
101
+ otherwise. A caller-chosen From is sender spoofing on infrastructure whose
102
+ DKIM signature makes it look authentic.
103
+
104
+ Raises:
105
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
106
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
107
+
108
+ Returns:
109
+ Response[Union[HTTPValidationError, SendResponseSend]]
110
+ """
111
+
112
+
113
+ kwargs = _get_kwargs(
114
+ body=body,
115
+ idempotency_key=idempotency_key,
116
+
117
+ )
118
+
119
+ response = client.get_httpx_client().request(
120
+ **kwargs,
121
+ )
122
+
123
+ return _build_response(client=client, response=response)
124
+
125
+ def sync(
126
+ *,
127
+ client: AuthenticatedClient,
128
+ body: SendRequest,
129
+ idempotency_key: Union[None, Unset, str] = UNSET,
130
+
131
+ ) -> Optional[Union[HTTPValidationError, SendResponseSend]]:
132
+ """ Send
133
+
134
+ Accept one outbound message.
135
+
136
+ The header is **mandatory**. An endpoint that sends email on a retryable
137
+ verb without one has no way to tell a retry from a second request, and the
138
+ caller cannot add idempotency afterwards.
139
+
140
+ Args:
141
+ idempotency_key (Union[None, Unset, str]):
142
+ body (SendRequest): `extra="forbid"` is load-bearing.
143
+
144
+ There is no `from`, `sender` or `return_path` field: the From identity comes
145
+ from the tenant's inbox record. Forbidding extras makes a caller who tries to
146
+ set one get a `422` instead of a silent `202` — being ignored is worse,
147
+ because the integrator believes they chose a sender and nothing says
148
+ otherwise. A caller-chosen From is sender spoofing on infrastructure whose
149
+ DKIM signature makes it look authentic.
150
+
151
+ Raises:
152
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
153
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
154
+
155
+ Returns:
156
+ Union[HTTPValidationError, SendResponseSend]
157
+ """
158
+
159
+
160
+ return sync_detailed(
161
+ client=client,
162
+ body=body,
163
+ idempotency_key=idempotency_key,
164
+
165
+ ).parsed
166
+
167
+ async def asyncio_detailed(
168
+ *,
169
+ client: AuthenticatedClient,
170
+ body: SendRequest,
171
+ idempotency_key: Union[None, Unset, str] = UNSET,
172
+
173
+ ) -> Response[Union[HTTPValidationError, SendResponseSend]]:
174
+ """ Send
175
+
176
+ Accept one outbound message.
177
+
178
+ The header is **mandatory**. An endpoint that sends email on a retryable
179
+ verb without one has no way to tell a retry from a second request, and the
180
+ caller cannot add idempotency afterwards.
181
+
182
+ Args:
183
+ idempotency_key (Union[None, Unset, str]):
184
+ body (SendRequest): `extra="forbid"` is load-bearing.
185
+
186
+ There is no `from`, `sender` or `return_path` field: the From identity comes
187
+ from the tenant's inbox record. Forbidding extras makes a caller who tries to
188
+ set one get a `422` instead of a silent `202` — being ignored is worse,
189
+ because the integrator believes they chose a sender and nothing says
190
+ otherwise. A caller-chosen From is sender spoofing on infrastructure whose
191
+ DKIM signature makes it look authentic.
192
+
193
+ Raises:
194
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
195
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
196
+
197
+ Returns:
198
+ Response[Union[HTTPValidationError, SendResponseSend]]
199
+ """
200
+
201
+
202
+ kwargs = _get_kwargs(
203
+ body=body,
204
+ idempotency_key=idempotency_key,
205
+
206
+ )
207
+
208
+ response = await client.get_async_httpx_client().request(
209
+ **kwargs
210
+ )
211
+
212
+ return _build_response(client=client, response=response)
213
+
214
+ async def asyncio(
215
+ *,
216
+ client: AuthenticatedClient,
217
+ body: SendRequest,
218
+ idempotency_key: Union[None, Unset, str] = UNSET,
219
+
220
+ ) -> Optional[Union[HTTPValidationError, SendResponseSend]]:
221
+ """ Send
222
+
223
+ Accept one outbound message.
224
+
225
+ The header is **mandatory**. An endpoint that sends email on a retryable
226
+ verb without one has no way to tell a retry from a second request, and the
227
+ caller cannot add idempotency afterwards.
228
+
229
+ Args:
230
+ idempotency_key (Union[None, Unset, str]):
231
+ body (SendRequest): `extra="forbid"` is load-bearing.
232
+
233
+ There is no `from`, `sender` or `return_path` field: the From identity comes
234
+ from the tenant's inbox record. Forbidding extras makes a caller who tries to
235
+ set one get a `422` instead of a silent `202` — being ignored is worse,
236
+ because the integrator believes they chose a sender and nothing says
237
+ otherwise. A caller-chosen From is sender spoofing on infrastructure whose
238
+ DKIM signature makes it look authentic.
239
+
240
+ Raises:
241
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
242
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
243
+
244
+ Returns:
245
+ Union[HTTPValidationError, SendResponseSend]
246
+ """
247
+
248
+
249
+ return (await asyncio_detailed(
250
+ client=client,
251
+ body=body,
252
+ idempotency_key=idempotency_key,
253
+
254
+ )).parsed