pangea-sdk 6.1.0__py3-none-any.whl → 6.2.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 (51) hide show
  1. pangea/__init__.py +9 -1
  2. pangea/asyncio/__init__.py +1 -0
  3. pangea/asyncio/file_uploader.py +4 -2
  4. pangea/asyncio/request.py +53 -18
  5. pangea/asyncio/services/__init__.py +2 -0
  6. pangea/asyncio/services/ai_guard.py +9 -12
  7. pangea/asyncio/services/audit.py +12 -7
  8. pangea/asyncio/services/authn.py +36 -25
  9. pangea/asyncio/services/authz.py +6 -6
  10. pangea/asyncio/services/base.py +4 -0
  11. pangea/asyncio/services/file_scan.py +8 -2
  12. pangea/asyncio/services/intel.py +26 -28
  13. pangea/asyncio/services/redact.py +7 -3
  14. pangea/asyncio/services/sanitize.py +5 -1
  15. pangea/asyncio/services/share.py +5 -1
  16. pangea/asyncio/services/vault.py +19 -15
  17. pangea/audit_logger.py +3 -1
  18. pangea/deep_verify.py +13 -13
  19. pangea/deprecated.py +1 -1
  20. pangea/dump_audit.py +2 -3
  21. pangea/exceptions.py +8 -5
  22. pangea/file_uploader.py +4 -0
  23. pangea/request.py +64 -48
  24. pangea/response.py +21 -18
  25. pangea/services/__init__.py +2 -0
  26. pangea/services/ai_guard.py +35 -24
  27. pangea/services/audit/audit.py +16 -13
  28. pangea/services/audit/models.py +71 -34
  29. pangea/services/audit/signing.py +1 -1
  30. pangea/services/audit/util.py +10 -10
  31. pangea/services/authn/authn.py +36 -25
  32. pangea/services/authn/models.py +10 -56
  33. pangea/services/authz.py +10 -6
  34. pangea/services/base.py +7 -4
  35. pangea/services/embargo.py +6 -0
  36. pangea/services/file_scan.py +8 -2
  37. pangea/services/intel.py +36 -19
  38. pangea/services/redact.py +7 -3
  39. pangea/services/sanitize.py +5 -1
  40. pangea/services/share/share.py +13 -7
  41. pangea/services/vault/models/asymmetric.py +4 -0
  42. pangea/services/vault/models/common.py +4 -0
  43. pangea/services/vault/models/symmetric.py +4 -0
  44. pangea/services/vault/vault.py +17 -19
  45. pangea/tools.py +13 -9
  46. pangea/utils.py +3 -5
  47. pangea/verify_audit.py +23 -27
  48. {pangea_sdk-6.1.0.dist-info → pangea_sdk-6.2.0.dist-info}/METADATA +36 -17
  49. pangea_sdk-6.2.0.dist-info/RECORD +60 -0
  50. {pangea_sdk-6.1.0.dist-info → pangea_sdk-6.2.0.dist-info}/WHEEL +1 -1
  51. pangea_sdk-6.1.0.dist-info/RECORD +0 -60
pangea/__init__.py CHANGED
@@ -1,7 +1,15 @@
1
- __version__ = "6.1.0"
1
+ __version__ = "6.2.0"
2
2
 
3
3
  from pangea.asyncio.request import PangeaRequestAsync
4
4
  from pangea.config import PangeaConfig
5
5
  from pangea.file_uploader import FileUploader
6
6
  from pangea.request import PangeaRequest
7
7
  from pangea.response import PangeaResponse
8
+
9
+ __all__ = (
10
+ "FileUploader",
11
+ "PangeaConfig",
12
+ "PangeaRequest",
13
+ "PangeaRequestAsync",
14
+ "PangeaResponse",
15
+ )
@@ -1 +1,2 @@
1
+ # ruff: noqa: F401
1
2
  from .file_uploader import FileUploaderAsync
@@ -1,8 +1,10 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+
4
+ from __future__ import annotations
5
+
3
6
  import io
4
7
  import logging
5
- from typing import Dict, Optional
6
8
 
7
9
  from pangea.asyncio.request import PangeaRequestAsync
8
10
  from pangea.request import PangeaConfig
@@ -24,7 +26,7 @@ class FileUploaderAsync:
24
26
  url: str,
25
27
  file: io.BufferedReader,
26
28
  transfer_method: TransferMethod = TransferMethod.PUT_URL,
27
- file_details: Optional[Dict] = None,
29
+ file_details: dict | None = None,
28
30
  ) -> None:
29
31
  if transfer_method == TransferMethod.PUT_URL:
30
32
  files = [("file", ("filename", file, "application/octet-stream"))]
pangea/asyncio/request.py CHANGED
@@ -1,23 +1,43 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+
4
+ # TODO: Modernize.
5
+ # ruff: noqa: UP006, UP035
6
+
3
7
  from __future__ import annotations
4
8
 
5
9
  import asyncio
6
10
  import json
7
11
  import time
12
+ from collections.abc import Iterable, Mapping
8
13
  from typing import Dict, List, Optional, Sequence, Tuple, Type, Union, cast
9
14
 
10
15
  import aiohttp
11
16
  from aiohttp import FormData
12
17
  from pydantic import BaseModel
13
18
  from pydantic_core import to_jsonable_python
14
- from typing_extensions import Any, TypeVar
19
+ from typing_extensions import Any, TypeAlias, TypeVar, override
15
20
 
16
21
  import pangea.exceptions as pe
17
22
  from pangea.request import MultipartResponse, PangeaRequestBase
18
23
  from pangea.response import AttachedFile, PangeaResponse, PangeaResponseResult, ResponseStatus, TransferMethod
19
24
  from pangea.utils import default_encoder
20
25
 
26
+ _FileName: TypeAlias = Union[str, None]
27
+ _FileContent: TypeAlias = Union[str, bytes]
28
+ _FileContentType: TypeAlias = str
29
+ _FileCustomHeaders: TypeAlias = Mapping[str, str]
30
+ _FileSpecTuple2: TypeAlias = tuple[_FileName, _FileContent]
31
+ _FileSpecTuple3: TypeAlias = tuple[_FileName, _FileContent, _FileContentType]
32
+ _FileSpecTuple4: TypeAlias = tuple[_FileName, _FileContent, _FileContentType, _FileCustomHeaders]
33
+ _FileSpec: TypeAlias = Union[_FileContent, _FileSpecTuple2, _FileSpecTuple3, _FileSpecTuple4]
34
+ _Files: TypeAlias = Union[Mapping[str, _FileSpec], Iterable[tuple[str, _FileSpec]]]
35
+ _LooseHeaders = Union[
36
+ Mapping[str, str],
37
+ Iterable[tuple[str, str]],
38
+ ]
39
+
40
+
21
41
  TResult = TypeVar("TResult", bound=PangeaResponseResult)
22
42
 
23
43
 
@@ -34,7 +54,7 @@ class PangeaRequestAsync(PangeaRequestBase):
34
54
  self,
35
55
  endpoint: str,
36
56
  result_class: Type[TResult],
37
- data: str | BaseModel | dict[str, Any] | None = None,
57
+ data: str | BaseModel | Mapping[str, Any] | None = None,
38
58
  files: Optional[List[Tuple]] = None,
39
59
  poll_result: bool = True,
40
60
  url: Optional[str] = None,
@@ -61,7 +81,7 @@ class PangeaRequestAsync(PangeaRequestBase):
61
81
  data = {}
62
82
 
63
83
  # Normalize.
64
- data = cast(dict[str, Any], to_jsonable_python(data))
84
+ data = cast(dict[str, Any], to_jsonable_python(data, exclude_none=True))
65
85
 
66
86
  if url is None:
67
87
  url = self._url(endpoint)
@@ -80,8 +100,11 @@ class PangeaRequestAsync(PangeaRequestBase):
80
100
  endpoint, result_class=result_class, data=data, files=files
81
101
  )
82
102
  else:
103
+ headers = self._headers()
104
+ if transfer_method == TransferMethod.MULTIPART.value:
105
+ del headers["Content-Type"]
83
106
  requests_response = await self._http_post(
84
- url, headers=self._headers(), data=data, files=files, presigned_url_post=False
107
+ url, headers=headers, data=data, files=files, presigned_url_post=False
85
108
  )
86
109
 
87
110
  await self._check_http_errors(requests_response)
@@ -103,7 +126,9 @@ class PangeaRequestAsync(PangeaRequestBase):
103
126
 
104
127
  pangea_response = PangeaResponse(requests_response, result_class=result_class, json=json_resp)
105
128
  except aiohttp.ContentTypeError as e:
106
- raise pe.PangeaException(f"Failed to decode json response. {e}. Body: {await requests_response.text()}")
129
+ raise pe.PangeaException(
130
+ f"Failed to decode json response. {e}. Body: {await requests_response.text()}"
131
+ ) from e
107
132
 
108
133
  if poll_result:
109
134
  pangea_response = await self._handle_queued_result(pangea_response)
@@ -164,7 +189,7 @@ class PangeaRequestAsync(PangeaRequestBase):
164
189
 
165
190
  return await self.poll_result_by_id(request_id, response.result_class, check_response=check_response)
166
191
 
167
- async def post_presigned_url(self, url: str, data: Dict, files: List[Tuple]):
192
+ async def post_presigned_url(self, url: str, data: dict[Any, Any], files: Sequence[Tuple]):
168
193
  # Send form request with file and upload_details as body
169
194
  resp = await self._http_post(url=url, data=data, files=files, presigned_url_post=True)
170
195
  self.logger.debug(
@@ -278,35 +303,44 @@ class PangeaRequestAsync(PangeaRequestBase):
278
303
  async def _http_post(
279
304
  self,
280
305
  url: str,
281
- headers: Dict = {},
282
- data: Union[str, Dict] = {},
283
- files: Optional[List[Tuple]] = [],
306
+ headers: _LooseHeaders = {}, # noqa: B006
307
+ data: str | dict[str, Any] | None = None,
308
+ files: _Files | None = None,
284
309
  presigned_url_post: bool = False,
285
310
  ) -> aiohttp.ClientResponse:
311
+ if data is None:
312
+ data = {}
313
+
286
314
  if files:
287
315
  form = FormData()
288
316
  if presigned_url_post:
289
- for k, v in data.items(): # type: ignore[union-attr]
317
+ assert isinstance(data, dict)
318
+ assert isinstance(files, list)
319
+ for k, v in data.items():
290
320
  form.add_field(k, v)
291
- for name, value in files:
321
+ for _name, value in files:
292
322
  form.add_field("file", value[1], filename=value[0], content_type=value[2])
293
323
  else:
294
- data_send = json.dumps(data, default=default_encoder) if isinstance(data, dict) else data
324
+ assert isinstance(files, list)
325
+ data_send: str | FormData = (
326
+ json.dumps(data, default=default_encoder) if isinstance(data, dict) else data
327
+ )
295
328
  form.add_field("request", data_send, content_type="application/json")
296
329
  for name, value in files:
297
330
  form.add_field(name, value[1], filename=value[0], content_type=value[2])
298
331
 
299
- data_send = form # type: ignore[assignment]
332
+ data_send = form
300
333
  else:
301
334
  data_send = json.dumps(data, default=default_encoder) if isinstance(data, dict) else data
302
335
 
336
+ assert isinstance(self.session, aiohttp.ClientSession)
303
337
  return await self.session.post(url, headers=headers, data=data_send)
304
338
 
305
339
  async def _http_put(
306
340
  self,
307
341
  url: str,
308
342
  files: Sequence[Tuple],
309
- headers: Dict = {},
343
+ headers: _LooseHeaders = {}, # noqa: B006
310
344
  ) -> aiohttp.ClientResponse:
311
345
  self.logger.debug(
312
346
  json.dumps({"service": self.service, "action": "http_put", "url": url}, default=default_encoder)
@@ -318,8 +352,8 @@ class PangeaRequestAsync(PangeaRequestBase):
318
352
  self,
319
353
  endpoint: str,
320
354
  result_class: Type[PangeaResponseResult],
321
- data: Union[str, Dict] = {},
322
- files: List[Tuple] = [],
355
+ data: Union[str, Mapping[str, Any]] = {},
356
+ files: Sequence[Tuple] = [],
323
357
  ):
324
358
  if len(files) == 0:
325
359
  raise AttributeError("files attribute should have at least 1 file")
@@ -343,7 +377,7 @@ class PangeaRequestAsync(PangeaRequestBase):
343
377
  self,
344
378
  endpoint: str,
345
379
  result_class: Type[PangeaResponseResult],
346
- data: Union[str, Dict] = {},
380
+ data: Union[str, Mapping[str, Any]] = {},
347
381
  ) -> PangeaResponse:
348
382
  # Send request
349
383
  try:
@@ -394,7 +428,7 @@ class PangeaRequestAsync(PangeaRequestBase):
394
428
  {"service": self.service, "action": "poll_presigned_url", "step": "exit", "cause": {str(e)}}
395
429
  )
396
430
  )
397
- raise pe.PresignedURLException("Failed to pull Presigned URL", loop_exc.response, e)
431
+ raise pe.PresignedURLException("Failed to pull Presigned URL", loop_exc.response, e) from e
398
432
 
399
433
  self.logger.debug(json.dumps({"service": self.service, "action": "poll_presigned_url", "step": "exit"}))
400
434
 
@@ -426,6 +460,7 @@ class PangeaRequestAsync(PangeaRequestBase):
426
460
  self.logger.debug(json.dumps({"service": self.service, "action": "poll_result_retry", "step": "exit"}))
427
461
  return self._check_response(response)
428
462
 
463
+ @override
429
464
  def _init_session(self) -> aiohttp.ClientSession:
430
465
  # retry_config = Retry(
431
466
  # total=self.config.request_retries,
@@ -1,3 +1,5 @@
1
+ # ruff: noqa: F401
2
+
1
3
  from .ai_guard import AIGuardAsync
2
4
  from .audit import AuditAsync
3
5
  from .authn import AuthNAsync
@@ -1,15 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from collections.abc import Sequence
3
4
  from typing import overload
4
5
 
5
- from typing_extensions import TypeVar
6
-
7
6
  from pangea.asyncio.services.base import ServiceBaseAsync
8
7
  from pangea.config import PangeaConfig
9
8
  from pangea.response import PangeaResponse
10
- from pangea.services.ai_guard import LogFields, Overrides, TextGuardResult
11
-
12
- _T = TypeVar("_T")
9
+ from pangea.services.ai_guard import LogFields, Message, Overrides, TextGuardResult
13
10
 
14
11
 
15
12
  class AIGuardAsync(ServiceBaseAsync):
@@ -60,7 +57,7 @@ class AIGuardAsync(ServiceBaseAsync):
60
57
  debug: bool | None = None,
61
58
  overrides: Overrides | None = None,
62
59
  log_fields: LogFields | None = None,
63
- ) -> PangeaResponse[TextGuardResult[None]]:
60
+ ) -> PangeaResponse[TextGuardResult]:
64
61
  """
65
62
  Text Guard for scanning LLM inputs and outputs
66
63
 
@@ -88,12 +85,12 @@ class AIGuardAsync(ServiceBaseAsync):
88
85
  async def guard_text(
89
86
  self,
90
87
  *,
91
- messages: _T,
88
+ messages: Sequence[Message],
92
89
  recipe: str | None = None,
93
90
  debug: bool | None = None,
94
91
  overrides: Overrides | None = None,
95
92
  log_fields: LogFields | None = None,
96
- ) -> PangeaResponse[TextGuardResult[_T]]:
93
+ ) -> PangeaResponse[TextGuardResult]:
97
94
  """
98
95
  Text Guard for scanning LLM inputs and outputs
99
96
 
@@ -115,19 +112,19 @@ class AIGuardAsync(ServiceBaseAsync):
115
112
  log_field: Additional fields to include in activity log
116
113
 
117
114
  Examples:
118
- response = await ai_guard.guard_text(messages=[{"role": "user", "content": "hello world"}])
115
+ response = await ai_guard.guard_text(messages=[Message(role="user", content="hello world")])
119
116
  """
120
117
 
121
- async def guard_text( # type: ignore[misc]
118
+ async def guard_text(
122
119
  self,
123
120
  text: str | None = None,
124
121
  *,
125
- messages: _T | None = None,
122
+ messages: Sequence[Message] | None = None,
126
123
  recipe: str | None = None,
127
124
  debug: bool | None = None,
128
125
  overrides: Overrides | None = None,
129
126
  log_fields: LogFields | None = None,
130
- ) -> PangeaResponse[TextGuardResult[None]]:
127
+ ) -> PangeaResponse[TextGuardResult]:
131
128
  """
132
129
  Text Guard for scanning LLM inputs and outputs
133
130
 
@@ -1,8 +1,13 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+
4
+ # TODO: Modernize.
5
+ # ruff: noqa: UP006, UP035
6
+
3
7
  from __future__ import annotations
4
8
 
5
9
  import datetime
10
+ from collections.abc import Mapping
6
11
  from typing import Any, Dict, Iterable, List, Optional, Sequence, Union
7
12
 
8
13
  import pangea.exceptions as pexc
@@ -63,7 +68,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
63
68
  token: str,
64
69
  config: PangeaConfig | None = None,
65
70
  private_key_file: str = "",
66
- public_key_info: dict[str, str] = {},
71
+ public_key_info: Mapping[str, str] = {},
67
72
  tenant_id: str | None = None,
68
73
  logger_name: str = "pangea",
69
74
  config_id: str | None = None,
@@ -135,7 +140,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
135
140
  A PangeaResponse where the hash of event data and optional verbose
136
141
  results are returned in the response.result field.
137
142
  Available response fields can be found in our
138
- [API documentation](https://pangea.cloud/docs/api/audit#log-an-entry).
143
+ [API documentation](https://pangea.cloud/docs/api/audit#/v1/log-post).
139
144
 
140
145
  Examples:
141
146
  try:
@@ -186,7 +191,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
186
191
  Returns:
187
192
  A PangeaResponse where the hash of event data and optional verbose
188
193
  results are returned in the response.result field.
189
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#log-an-entry).
194
+ Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/log-post).
190
195
 
191
196
  Examples:
192
197
  response = await audit.log_event({"message": "hello world"}, verbose=True)
@@ -222,7 +227,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
222
227
  Returns:
223
228
  A PangeaResponse where the hash of event data and optional verbose
224
229
  results are returned in the response.result field.
225
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#log-an-entry).
230
+ Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/log-post).
226
231
 
227
232
  Examples:
228
233
  FIXME:
@@ -259,7 +264,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
259
264
  Returns:
260
265
  A PangeaResponse where the hash of event data and optional verbose
261
266
  results are returned in the response.result field.
262
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#log-an-entry).
267
+ Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/log-post).
263
268
 
264
269
  Examples:
265
270
  FIXME:
@@ -328,8 +333,8 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
328
333
 
329
334
  Returns:
330
335
  A PangeaResponse[SearchOutput] where the first page of matched events is returned in the
331
- response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#search-for-events).
332
- Pagination can be found in the [search results endpoint](https://pangea.cloud/docs/api/audit#search-results).
336
+ response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/results-post).
337
+ Pagination can be found in the [search results endpoint](https://pangea.cloud/docs/api/audit#/v1/download_results-post).
333
338
 
334
339
  Examples:
335
340
  response: PangeaResponse[SearchOutput] = audit.search(query="message:test", search_restriction={'source': ["monitor"]}, limit=1, verify_consistency=True, verify_events=True)
@@ -1,7 +1,12 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+
4
+ # TODO: Modernize.
5
+ # ruff: noqa: UP006, UP035
6
+
3
7
  from __future__ import annotations
4
8
 
9
+ from collections.abc import Mapping
5
10
  from typing import Dict, List, Literal, Optional, Union
6
11
 
7
12
  import pangea.services.authn.models as m
@@ -127,7 +132,7 @@ class AuthNAsync(ServiceBaseAsync):
127
132
  Returns:
128
133
  A PangeaResponse with a list of sessions in the response.result field.
129
134
  Available response fields can be found in our
130
- [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/session/list).
135
+ [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/session/list-post).
131
136
 
132
137
  Examples:
133
138
  response = authn.session.list()
@@ -192,7 +197,7 @@ class AuthNAsync(ServiceBaseAsync):
192
197
  Returns:
193
198
  A PangeaResponse with credentials for a login session in the response.result field.
194
199
  Available response fields can be found in our
195
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/client/userinfo).
200
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/client/userinfo-post).
196
201
 
197
202
  Examples:
198
203
  response = authn.client.userinfo(
@@ -217,7 +222,7 @@ class AuthNAsync(ServiceBaseAsync):
217
222
  Returns:
218
223
  A PangeaResponse with jwt verification keys in the response.result field.
219
224
  Available response fields can be found in our
220
- [API Documentation](https://pangea.cloud/docs/api/authn/jwt#/v2/client/jwks).
225
+ [API Documentation](https://pangea.cloud/docs/api/authn/jwt#/v2/client/jwks-post).
221
226
 
222
227
  Examples:
223
228
  response = authn.client.jwks()
@@ -290,7 +295,7 @@ class AuthNAsync(ServiceBaseAsync):
290
295
  Returns:
291
296
  A PangeaResponse with a list of sessions in the response.result field.
292
297
  Available response fields can be found in our
293
- [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/list).
298
+ [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/list-post).
294
299
 
295
300
  Examples:
296
301
  response = authn.client.session.list(
@@ -348,7 +353,7 @@ class AuthNAsync(ServiceBaseAsync):
348
353
  Returns:
349
354
  A PangeaResponse with credentials for a login session in the response.result field.
350
355
  Available response fields can be found in our
351
- [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/refresh).
356
+ [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/refresh-post).
352
357
 
353
358
  Examples:
354
359
  response = authn.client.session.refresh(
@@ -446,7 +451,7 @@ class AuthNAsync(ServiceBaseAsync):
446
451
  Returns:
447
452
  A PangeaResponse with a token and its information in the response.result field.
448
453
  Available response fields can be found in our
449
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/client/token/check).
454
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/client/token/check-post).
450
455
 
451
456
  Examples:
452
457
  response = authn.client.token_endpoints.check(
@@ -475,7 +480,7 @@ class AuthNAsync(ServiceBaseAsync):
475
480
  async def create(
476
481
  self,
477
482
  email: str,
478
- profile: m.Profile,
483
+ profile: Mapping[str, str],
479
484
  *,
480
485
  username: str | None = None,
481
486
  ) -> PangeaResponse[m.UserCreateResult]:
@@ -494,7 +499,7 @@ class AuthNAsync(ServiceBaseAsync):
494
499
  Returns:
495
500
  A PangeaResponse with a user and its information in the response.result field.
496
501
  Available response fields can be found in our
497
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/create).
502
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/create-post).
498
503
 
499
504
  Examples:
500
505
  response = authn.user.create(
@@ -563,7 +568,7 @@ class AuthNAsync(ServiceBaseAsync):
563
568
  Returns:
564
569
  A PangeaResponse with a pending user invitation in the response.result field.
565
570
  Available response fields can be found in our
566
- [API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite).
571
+ [API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite-post).
567
572
 
568
573
  Examples:
569
574
  response = authn.user.invite(
@@ -608,7 +613,7 @@ class AuthNAsync(ServiceBaseAsync):
608
613
  Returns:
609
614
  A PangeaResponse with a user and its information in the response.result field.
610
615
  Available response fields can be found in our
611
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/update).
616
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/update-post).
612
617
 
613
618
  Examples:
614
619
  response = authn.user.update(
@@ -652,7 +657,7 @@ class AuthNAsync(ServiceBaseAsync):
652
657
  Returns:
653
658
  A PangeaResponse with a list of users in the response.result field.
654
659
  Available response fields can be found in our
655
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/list).
660
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/list-post).
656
661
 
657
662
  Examples:
658
663
  response = authn.user.list()
@@ -705,7 +710,7 @@ class AuthNAsync(ServiceBaseAsync):
705
710
  Returns:
706
711
  A PangeaResponse with a list of pending user invitations in the response.result field.
707
712
  Available response fields can be found in our
708
- [API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite/list).
713
+ [API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite/list-post).
709
714
  Examples:
710
715
  response = authn.user.invites.list()
711
716
  """
@@ -809,7 +814,7 @@ class AuthNAsync(ServiceBaseAsync):
809
814
  Returns:
810
815
  A PangeaResponse with a list of authenticators in the response.result field.
811
816
  Available response fields can be found in our
812
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/authenticators/list).
817
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/authenticators/list-post).
813
818
 
814
819
  Examples:
815
820
  response = authn.user.authenticators.list(
@@ -852,7 +857,7 @@ class AuthNAsync(ServiceBaseAsync):
852
857
  Returns:
853
858
  A PangeaResponse with a user and its information in the response.result field.
854
859
  Available response fields can be found in our
855
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/get).
860
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/get-post).
856
861
 
857
862
  Examples:
858
863
  response = authn.user.profile.get(
@@ -866,7 +871,7 @@ class AuthNAsync(ServiceBaseAsync):
866
871
 
867
872
  async def update(
868
873
  self,
869
- profile: m.Profile,
874
+ profile: Mapping[str, str],
870
875
  id: str | None = None,
871
876
  email: str | None = None,
872
877
  *,
@@ -888,7 +893,7 @@ class AuthNAsync(ServiceBaseAsync):
888
893
  Returns:
889
894
  A PangeaResponse with a user and its information in the response.result field.
890
895
  Available response fields can be found in our
891
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/update).
896
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/update-post).
892
897
 
893
898
  Examples:
894
899
  response = authn.user.profile.update(
@@ -982,7 +987,7 @@ class AuthNAsync(ServiceBaseAsync):
982
987
  Returns:
983
988
  A PangeaResponse with credentials for a login session in the response.result field.
984
989
  Available response fields can be found in our
985
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/complete).
990
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/complete-post).
986
991
 
987
992
  Examples:
988
993
  response = authn.flow.complete(
@@ -995,7 +1000,10 @@ class AuthNAsync(ServiceBaseAsync):
995
1000
  )
996
1001
 
997
1002
  async def restart(
998
- self, flow_id: str, choice: m.FlowChoice, data: m.FlowRestartData = {}
1003
+ self,
1004
+ flow_id: str,
1005
+ choice: m.FlowChoice,
1006
+ data: m.FlowRestartData = {}, # noqa: B006
999
1007
  ) -> PangeaResponse[m.FlowRestartResult]:
1000
1008
  """
1001
1009
  Restart a sign-up/sign-in flow
@@ -1013,7 +1021,7 @@ class AuthNAsync(ServiceBaseAsync):
1013
1021
  A PangeaResponse with information about next steps needed
1014
1022
  to complete a flow in the response.result field.
1015
1023
  Available response fields can be found in our
1016
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/restart).
1024
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/restart-post).
1017
1025
 
1018
1026
  Examples:
1019
1027
  response = authn.flow.restart(
@@ -1052,7 +1060,7 @@ class AuthNAsync(ServiceBaseAsync):
1052
1060
  A PangeaResponse with information about next steps needed
1053
1061
  to complete a flow in the response.result field.
1054
1062
  Available response fields can be found in our
1055
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/start).
1063
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/start-post).
1056
1064
 
1057
1065
  Examples:
1058
1066
  response = authn.flow.start(
@@ -1068,7 +1076,10 @@ class AuthNAsync(ServiceBaseAsync):
1068
1076
  return await self.request.post("v2/flow/start", m.FlowStartResult, data=input.model_dump(exclude_none=True))
1069
1077
 
1070
1078
  async def update(
1071
- self, flow_id: str, choice: m.FlowChoice, data: m.FlowUpdateData = {}
1079
+ self,
1080
+ flow_id: str,
1081
+ choice: m.FlowChoice,
1082
+ data: m.FlowUpdateData = {}, # noqa: B006
1072
1083
  ) -> PangeaResponse[m.FlowUpdateResult]:
1073
1084
  """
1074
1085
  Update a sign-up/sign-in flow
@@ -1086,7 +1097,7 @@ class AuthNAsync(ServiceBaseAsync):
1086
1097
  A PangeaResponse with information about next steps needed
1087
1098
  to complete a flow in the response.result field.
1088
1099
  Available response fields can be found in our
1089
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/update).
1100
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/update-post).
1090
1101
 
1091
1102
  Examples:
1092
1103
  response = authn.flow.update(
@@ -1133,7 +1144,7 @@ class AuthNAsync(ServiceBaseAsync):
1133
1144
  Returns:
1134
1145
  A PangeaResponse with a EULA object in the response.result field.
1135
1146
  Available response fields can be found in our
1136
- [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/create).
1147
+ [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/create-post).
1137
1148
 
1138
1149
  Examples:
1139
1150
  response = authn.agreements.create(
@@ -1200,7 +1211,7 @@ class AuthNAsync(ServiceBaseAsync):
1200
1211
  Returns:
1201
1212
  A PangeaResponse with a list of EULA objects in the response.result field.
1202
1213
  Available response fields can be found in our
1203
- [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/list).
1214
+ [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/list-post).
1204
1215
 
1205
1216
  Examples:
1206
1217
  response = authn.agreements.list()
@@ -1238,7 +1249,7 @@ class AuthNAsync(ServiceBaseAsync):
1238
1249
  Returns:
1239
1250
  A PangeaResponse with the updated EULA object in the response.result field.
1240
1251
  Available response fields can be found in our
1241
- [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/update).
1252
+ [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/update-post).
1242
1253
 
1243
1254
  Examples:
1244
1255
  response = authn.agreements.update(
@@ -88,7 +88,7 @@ class AuthZAsync(ServiceBaseAsync):
88
88
  Returns:
89
89
  Pangea Response with empty result.
90
90
  Available response fields can be found in our
91
- [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/create).
91
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/create-post).
92
92
 
93
93
  Examples:
94
94
  await authz.tuple_create(
@@ -134,7 +134,7 @@ class AuthZAsync(ServiceBaseAsync):
134
134
  Returns:
135
135
  Pangea Response with a list of tuples and the last token.
136
136
  Available response fields can be found in our
137
- [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/list).
137
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/list-post).
138
138
 
139
139
  Examples:
140
140
  await authz.tuple_list(TupleListFilter(subject_type="user", subject_id="user_1"))
@@ -158,7 +158,7 @@ class AuthZAsync(ServiceBaseAsync):
158
158
  Returns:
159
159
  Pangea Response with empty result.
160
160
  Available response fields can be found in our
161
- [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/delete).
161
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/delete-post).
162
162
 
163
163
  Examples:
164
164
  await authz.tuple_delete(
@@ -202,7 +202,7 @@ class AuthZAsync(ServiceBaseAsync):
202
202
  Returns:
203
203
  Pangea Response with the result of the check.
204
204
  Available response fields can be found in our
205
- [API Documentation](https://pangea.cloud/docs/api/authz#/v1/check).
205
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/check-post).
206
206
 
207
207
  Examples:
208
208
  await authz.check(
@@ -236,7 +236,7 @@ class AuthZAsync(ServiceBaseAsync):
236
236
  Returns:
237
237
  Pangea Response with a list of resource IDs.
238
238
  Available response fields can be found in our
239
- [API Documentation](https://pangea.cloud/docs/api/authz#/v1/list-resources).
239
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/list-resources-post).
240
240
 
241
241
  Examples:
242
242
  await authz.list_resources(
@@ -270,7 +270,7 @@ class AuthZAsync(ServiceBaseAsync):
270
270
  Returns:
271
271
  Pangea Response with a list of subjects.
272
272
  Available response fields can be found in our
273
- [API Documentation](https://pangea.cloud/docs/api/authz#/v1/list-subjects).
273
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/list-subjects-post).
274
274
 
275
275
  Examples:
276
276
  await authz.list_subjects(