pangea-sdk 6.2.0b1__py3-none-any.whl → 6.2.0b2__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 (54) 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 +51 -21
  5. pangea/asyncio/services/__init__.py +2 -0
  6. pangea/asyncio/services/ai_guard.py +91 -2
  7. pangea/asyncio/services/audit.py +14 -8
  8. pangea/asyncio/services/authn.py +33 -23
  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 +6 -2
  13. pangea/asyncio/services/prompt_guard.py +112 -2
  14. pangea/asyncio/services/redact.py +7 -3
  15. pangea/asyncio/services/sanitize.py +5 -1
  16. pangea/asyncio/services/share.py +5 -1
  17. pangea/asyncio/services/vault.py +19 -15
  18. pangea/audit_logger.py +3 -1
  19. pangea/deep_verify.py +13 -13
  20. pangea/deprecated.py +1 -1
  21. pangea/dump_audit.py +2 -3
  22. pangea/exceptions.py +8 -5
  23. pangea/file_uploader.py +4 -0
  24. pangea/request.py +58 -41
  25. pangea/response.py +15 -12
  26. pangea/services/__init__.py +2 -0
  27. pangea/services/ai_guard.py +497 -16
  28. pangea/services/audit/audit.py +15 -13
  29. pangea/services/audit/models.py +4 -0
  30. pangea/services/audit/signing.py +1 -1
  31. pangea/services/audit/util.py +10 -10
  32. pangea/services/authn/authn.py +33 -23
  33. pangea/services/authn/models.py +3 -0
  34. pangea/services/authz.py +10 -6
  35. pangea/services/base.py +5 -1
  36. pangea/services/embargo.py +6 -0
  37. pangea/services/file_scan.py +8 -2
  38. pangea/services/intel.py +4 -0
  39. pangea/services/management.py +8 -8
  40. pangea/services/prompt_guard.py +193 -2
  41. pangea/services/redact.py +7 -3
  42. pangea/services/sanitize.py +5 -1
  43. pangea/services/share/share.py +13 -7
  44. pangea/services/vault/models/asymmetric.py +4 -0
  45. pangea/services/vault/models/common.py +4 -0
  46. pangea/services/vault/models/symmetric.py +4 -0
  47. pangea/services/vault/vault.py +17 -19
  48. pangea/tools.py +13 -9
  49. pangea/utils.py +3 -5
  50. pangea/verify_audit.py +23 -27
  51. {pangea_sdk-6.2.0b1.dist-info → pangea_sdk-6.2.0b2.dist-info}/METADATA +6 -6
  52. pangea_sdk-6.2.0b2.dist-info/RECORD +62 -0
  53. {pangea_sdk-6.2.0b1.dist-info → pangea_sdk-6.2.0b2.dist-info}/WHEEL +1 -1
  54. pangea_sdk-6.2.0b1.dist-info/RECORD +0 -62
pangea/__init__.py CHANGED
@@ -1,7 +1,15 @@
1
- __version__ = "6.2.0beta1"
1
+ __version__ = "6.2.0beta2"
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,24 +1,39 @@
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
8
12
  from collections.abc import Iterable, Mapping
9
- from typing import Dict, List, Literal, Optional, Sequence, Tuple, Type, Union, cast, overload
13
+ from typing import Dict, List, Optional, Sequence, Tuple, Type, Union, cast, overload
10
14
 
11
15
  import aiohttp
12
16
  from aiohttp import FormData
13
17
  from pydantic import BaseModel, TypeAdapter
14
18
  from pydantic_core import to_jsonable_python
15
- from typing_extensions import Any, TypeVar
19
+ from typing_extensions import Any, Literal, TypeAlias, TypeVar, override
16
20
 
17
21
  import pangea.exceptions as pe
18
22
  from pangea.request import MultipartResponse, PangeaRequestBase
19
23
  from pangea.response import AttachedFile, PangeaResponse, PangeaResponseResult, ResponseStatus, TransferMethod
20
24
  from pangea.utils import default_encoder
21
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
+
36
+
22
37
  TResult = TypeVar("TResult", bound=PangeaResponseResult)
23
38
 
24
39
 
@@ -53,7 +68,7 @@ class PangeaRequestAsync(PangeaRequestBase):
53
68
  self,
54
69
  endpoint: str,
55
70
  result_class: Type[TResult],
56
- data: str | BaseModel | dict[str, Any] | None = None,
71
+ data: str | BaseModel | Mapping[str, Any] | None = None,
57
72
  files: Optional[List[Tuple]] = None,
58
73
  poll_result: bool = True,
59
74
  url: Optional[str] = None,
@@ -77,7 +92,7 @@ class PangeaRequestAsync(PangeaRequestBase):
77
92
  self,
78
93
  endpoint: str,
79
94
  result_class: Type[TResult],
80
- data: str | BaseModel | dict[str, Any] | None = None,
95
+ data: str | BaseModel | Mapping[str, Any] | None = None,
81
96
  files: Optional[List[Tuple]] = None,
82
97
  poll_result: bool = True,
83
98
  url: Optional[str] = None,
@@ -96,7 +111,7 @@ class PangeaRequestAsync(PangeaRequestBase):
96
111
  self,
97
112
  endpoint: str,
98
113
  result_class: Type[TResult],
99
- data: str | BaseModel | dict[str, Any] | None = None,
114
+ data: str | BaseModel | Mapping[str, Any] | None = None,
100
115
  files: Optional[List[Tuple]] = None,
101
116
  poll_result: bool = True,
102
117
  url: Optional[str] = None,
@@ -122,7 +137,7 @@ class PangeaRequestAsync(PangeaRequestBase):
122
137
  data = {}
123
138
 
124
139
  # Normalize.
125
- data = cast(dict[str, Any], to_jsonable_python(data))
140
+ data = cast(dict[str, Any], to_jsonable_python(data, exclude_none=True))
126
141
 
127
142
  if url is None:
128
143
  url = self._url(endpoint)
@@ -141,8 +156,11 @@ class PangeaRequestAsync(PangeaRequestBase):
141
156
  endpoint, result_class=result_class, data=data, files=files
142
157
  )
143
158
  else:
159
+ headers = self._headers()
160
+ if transfer_method == TransferMethod.MULTIPART.value:
161
+ del headers["Content-Type"]
144
162
  requests_response = await self._http_post(
145
- url, headers=self._headers(), data=data, files=files, presigned_url_post=False
163
+ url, headers=headers, data=data, files=files, presigned_url_post=False
146
164
  )
147
165
 
148
166
  await self._check_http_errors(requests_response)
@@ -168,7 +186,9 @@ class PangeaRequestAsync(PangeaRequestBase):
168
186
 
169
187
  pangea_response_obj = PangeaResponse(requests_response, result_class=result_class, json=json_resp)
170
188
  except aiohttp.ContentTypeError as e:
171
- raise pe.PangeaException(f"Failed to decode json response. {e}. Body: {await requests_response.text()}")
189
+ raise pe.PangeaException(
190
+ f"Failed to decode json response. {e}. Body: {await requests_response.text()}"
191
+ ) from e
172
192
 
173
193
  if poll_result:
174
194
  pangea_response_obj = await self._handle_queued_result(pangea_response_obj)
@@ -290,7 +310,7 @@ class PangeaRequestAsync(PangeaRequestBase):
290
310
 
291
311
  return await self.poll_result_by_id(request_id, response.result_class, check_response=check_response)
292
312
 
293
- async def post_presigned_url(self, url: str, data: Dict, files: List[Tuple]):
313
+ async def post_presigned_url(self, url: str, data: dict[Any, Any], files: Sequence[Tuple]):
294
314
  # Send form request with file and upload_details as body
295
315
  resp = await self._http_post(url=url, data=data, files=files, presigned_url_post=True)
296
316
  self.logger.debug(
@@ -412,35 +432,44 @@ class PangeaRequestAsync(PangeaRequestBase):
412
432
  async def _http_post(
413
433
  self,
414
434
  url: str,
415
- headers: Mapping[str, str | bytes | None] = {},
416
- data: Union[str, Dict] = {},
417
- files: Optional[List[Tuple]] = [],
435
+ headers: Mapping[str, str] = {},
436
+ data: str | dict[str, Any] | None = None,
437
+ files: _Files | None = None,
418
438
  presigned_url_post: bool = False,
419
439
  ) -> aiohttp.ClientResponse:
440
+ if data is None:
441
+ data = {}
442
+
420
443
  if files:
421
444
  form = FormData()
422
445
  if presigned_url_post:
423
- for k, v in data.items(): # type: ignore[union-attr]
446
+ assert isinstance(data, dict)
447
+ assert isinstance(files, list)
448
+ for k, v in data.items():
424
449
  form.add_field(k, v)
425
- for name, value in files:
450
+ for _name, value in files:
426
451
  form.add_field("file", value[1], filename=value[0], content_type=value[2])
427
452
  else:
428
- data_send = json.dumps(data, default=default_encoder) if isinstance(data, dict) else data
453
+ assert isinstance(files, list)
454
+ data_send: str | FormData = (
455
+ json.dumps(data, default=default_encoder) if isinstance(data, dict) else data
456
+ )
429
457
  form.add_field("request", data_send, content_type="application/json")
430
458
  for name, value in files:
431
459
  form.add_field(name, value[1], filename=value[0], content_type=value[2])
432
460
 
433
- data_send = form # type: ignore[assignment]
461
+ data_send = form
434
462
  else:
435
463
  data_send = json.dumps(data, default=default_encoder) if isinstance(data, dict) else data
436
464
 
465
+ assert isinstance(self.session, aiohttp.ClientSession)
437
466
  return await self.session.post(url, headers=headers, data=data_send)
438
467
 
439
468
  async def _http_put(
440
469
  self,
441
470
  url: str,
442
471
  files: Sequence[Tuple],
443
- headers: Dict = {},
472
+ headers: Mapping[str, str] = {},
444
473
  ) -> aiohttp.ClientResponse:
445
474
  self.logger.debug(
446
475
  json.dumps({"service": self.service, "action": "http_put", "url": url}, default=default_encoder)
@@ -452,8 +481,8 @@ class PangeaRequestAsync(PangeaRequestBase):
452
481
  self,
453
482
  endpoint: str,
454
483
  result_class: Type[PangeaResponseResult],
455
- data: Union[str, Dict] = {},
456
- files: List[Tuple] = [],
484
+ data: Union[str, Mapping[str, Any]] = {},
485
+ files: Sequence[Tuple] = [],
457
486
  ):
458
487
  if len(files) == 0:
459
488
  raise AttributeError("files attribute should have at least 1 file")
@@ -477,7 +506,7 @@ class PangeaRequestAsync(PangeaRequestBase):
477
506
  self,
478
507
  endpoint: str,
479
508
  result_class: Type[PangeaResponseResult],
480
- data: Union[str, Dict] = {},
509
+ data: Union[str, Mapping[str, Any]] = {},
481
510
  ) -> PangeaResponse:
482
511
  # Send request
483
512
  try:
@@ -528,7 +557,7 @@ class PangeaRequestAsync(PangeaRequestBase):
528
557
  {"service": self.service, "action": "poll_presigned_url", "step": "exit", "cause": {str(e)}}
529
558
  )
530
559
  )
531
- raise pe.PresignedURLException("Failed to pull Presigned URL", loop_exc.response, e)
560
+ raise pe.PresignedURLException("Failed to pull Presigned URL", loop_exc.response, e) from e
532
561
 
533
562
  self.logger.debug(json.dumps({"service": self.service, "action": "poll_presigned_url", "step": "exit"}))
534
563
 
@@ -560,6 +589,7 @@ class PangeaRequestAsync(PangeaRequestBase):
560
589
  self.logger.debug(json.dumps({"service": self.service, "action": "poll_result_retry", "step": "exit"}))
561
590
  return self._check_response(response)
562
591
 
592
+ @override
563
593
  def _init_session(self) -> aiohttp.ClientSession:
564
594
  # retry_config = Retry(
565
595
  # 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,13 +1,24 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from collections.abc import Mapping
3
4
  from typing import overload
4
5
 
5
- from typing_extensions import TypeVar
6
+ from typing_extensions import Literal, TypeVar
6
7
 
7
8
  from pangea.asyncio.services.base import ServiceBaseAsync
8
9
  from pangea.config import PangeaConfig
9
10
  from pangea.response import PangeaResponse
10
- from pangea.services.ai_guard import LogFields, Overrides, TextGuardResult
11
+ from pangea.services.ai_guard import (
12
+ AuditDataActivityConfig,
13
+ ConnectionsConfig,
14
+ LogFields,
15
+ Overrides,
16
+ RecipeConfig,
17
+ ServiceConfig,
18
+ ServiceConfigFilter,
19
+ ServiceConfigsPage,
20
+ TextGuardResult,
21
+ )
11
22
 
12
23
  _T = TypeVar("_T")
13
24
 
@@ -170,3 +181,81 @@ class AIGuardAsync(ServiceBaseAsync):
170
181
  "log_fields": log_fields,
171
182
  },
172
183
  )
184
+
185
+ async def get_service_config(self, id: str) -> PangeaResponse[ServiceConfig]:
186
+ """
187
+ OperationId: ai_guard_post_v1beta_config
188
+ """
189
+ return await self.request.post("v1beta/config", data={"id": id}, result_class=ServiceConfig)
190
+
191
+ async def create_service_config(
192
+ self,
193
+ name: str,
194
+ *,
195
+ id: str | None = None,
196
+ audit_data_activity: AuditDataActivityConfig | None = None,
197
+ connections: ConnectionsConfig | None = None,
198
+ recipes: Mapping[str, RecipeConfig] | None = None,
199
+ ) -> PangeaResponse[ServiceConfig]:
200
+ """
201
+ OperationId: ai_guard_post_v1beta_config_create
202
+ """
203
+ return await self.request.post(
204
+ "v1beta/config/create",
205
+ data={
206
+ "name": name,
207
+ "id": id,
208
+ "audit_data_activity": audit_data_activity,
209
+ "connections": connections,
210
+ "recipes": recipes,
211
+ },
212
+ result_class=ServiceConfig,
213
+ )
214
+
215
+ async def update_service_config(
216
+ self,
217
+ id: str,
218
+ name: str,
219
+ *,
220
+ audit_data_activity: AuditDataActivityConfig | None = None,
221
+ connections: ConnectionsConfig | None = None,
222
+ recipes: Mapping[str, RecipeConfig] | None = None,
223
+ ) -> PangeaResponse[ServiceConfig]:
224
+ """
225
+ OperationId: ai_guard_post_v1beta_config_update
226
+ """
227
+ return await self.request.post(
228
+ "v1beta/config/update",
229
+ data={
230
+ "id": id,
231
+ "name": name,
232
+ "audit_data_activity": audit_data_activity,
233
+ "connections": connections,
234
+ "recipes": recipes,
235
+ },
236
+ result_class=ServiceConfig,
237
+ )
238
+
239
+ async def delete_service_config(self, id: str) -> PangeaResponse[ServiceConfig]:
240
+ """
241
+ OperationId: ai_guard_post_v1beta_config_delete
242
+ """
243
+ return await self.request.post("v1beta/config/delete", data={"id": id}, result_class=ServiceConfig)
244
+
245
+ async def list_service_configs(
246
+ self,
247
+ *,
248
+ filter: ServiceConfigFilter | None = None,
249
+ last: str | None = None,
250
+ order: Literal["asc", "desc"] | None = None,
251
+ order_by: Literal["id", "created_at", "updated_at"] | None = None,
252
+ size: int | None = None,
253
+ ) -> PangeaResponse[ServiceConfigsPage]:
254
+ """
255
+ OperationId: ai_guard_post_v1beta_config_list
256
+ """
257
+ return await self.request.post(
258
+ "v1beta/config/list",
259
+ data={"filter": filter, "last": last, "order": order, "order_by": order_by, "size": size},
260
+ result_class=ServiceConfigsPage,
261
+ )
@@ -1,11 +1,17 @@
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
6
- from typing import Any, Dict, Iterable, List, Literal, Optional, Sequence, Union, cast, overload
10
+ from collections.abc import Mapping
11
+ from typing import Any, Dict, Iterable, List, Optional, Sequence, Union, cast, overload
7
12
 
8
13
  from pydantic import TypeAdapter
14
+ from typing_extensions import Literal
9
15
 
10
16
  import pangea.exceptions as pexc
11
17
  from pangea.asyncio.services.base import ServiceBaseAsync
@@ -70,7 +76,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
70
76
  token: str,
71
77
  config: PangeaConfig | None = None,
72
78
  private_key_file: str = "",
73
- public_key_info: dict[str, str] = {},
79
+ public_key_info: Mapping[str, str] = {},
74
80
  tenant_id: str | None = None,
75
81
  logger_name: str = "pangea",
76
82
  config_id: str | None = None,
@@ -142,7 +148,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
142
148
  A PangeaResponse where the hash of event data and optional verbose
143
149
  results are returned in the response.result field.
144
150
  Available response fields can be found in our
145
- [API documentation](https://pangea.cloud/docs/api/audit#log-an-entry).
151
+ [API documentation](https://pangea.cloud/docs/api/audit#/v1/log-post).
146
152
 
147
153
  Examples:
148
154
  try:
@@ -193,7 +199,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
193
199
  Returns:
194
200
  A PangeaResponse where the hash of event data and optional verbose
195
201
  results are returned in the response.result field.
196
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#log-an-entry).
202
+ Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/log-post).
197
203
 
198
204
  Examples:
199
205
  response = await audit.log_event({"message": "hello world"}, verbose=True)
@@ -229,7 +235,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
229
235
  Returns:
230
236
  A PangeaResponse where the hash of event data and optional verbose
231
237
  results are returned in the response.result field.
232
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#log-an-entry).
238
+ Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/log-post).
233
239
 
234
240
  Examples:
235
241
  FIXME:
@@ -266,7 +272,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
266
272
  Returns:
267
273
  A PangeaResponse where the hash of event data and optional verbose
268
274
  results are returned in the response.result field.
269
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#log-an-entry).
275
+ Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/log-post).
270
276
 
271
277
  Examples:
272
278
  FIXME:
@@ -335,8 +341,8 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
335
341
 
336
342
  Returns:
337
343
  A PangeaResponse[SearchOutput] where the first page of matched events is returned in the
338
- response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#search-for-events).
339
- Pagination can be found in the [search results endpoint](https://pangea.cloud/docs/api/audit#search-results).
344
+ response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/results-post).
345
+ Pagination can be found in the [search results endpoint](https://pangea.cloud/docs/api/audit#/v1/download_results-post).
340
346
 
341
347
  Examples:
342
348
  response: PangeaResponse[SearchOutput] = audit.search(query="message:test", search_restriction={'source': ["monitor"]}, limit=1, verify_consistency=True, verify_events=True)
@@ -1,5 +1,9 @@
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
  from typing import Dict, List, Literal, Optional, Union
@@ -127,7 +131,7 @@ class AuthNAsync(ServiceBaseAsync):
127
131
  Returns:
128
132
  A PangeaResponse with a list of sessions in the response.result field.
129
133
  Available response fields can be found in our
130
- [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/session/list).
134
+ [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/session/list-post).
131
135
 
132
136
  Examples:
133
137
  response = authn.session.list()
@@ -192,7 +196,7 @@ class AuthNAsync(ServiceBaseAsync):
192
196
  Returns:
193
197
  A PangeaResponse with credentials for a login session in the response.result field.
194
198
  Available response fields can be found in our
195
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/client/userinfo).
199
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/client/userinfo-post).
196
200
 
197
201
  Examples:
198
202
  response = authn.client.userinfo(
@@ -217,7 +221,7 @@ class AuthNAsync(ServiceBaseAsync):
217
221
  Returns:
218
222
  A PangeaResponse with jwt verification keys in the response.result field.
219
223
  Available response fields can be found in our
220
- [API Documentation](https://pangea.cloud/docs/api/authn/jwt#/v2/client/jwks).
224
+ [API Documentation](https://pangea.cloud/docs/api/authn/jwt#/v2/client/jwks-post).
221
225
 
222
226
  Examples:
223
227
  response = authn.client.jwks()
@@ -290,7 +294,7 @@ class AuthNAsync(ServiceBaseAsync):
290
294
  Returns:
291
295
  A PangeaResponse with a list of sessions in the response.result field.
292
296
  Available response fields can be found in our
293
- [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/list).
297
+ [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/list-post).
294
298
 
295
299
  Examples:
296
300
  response = authn.client.session.list(
@@ -348,7 +352,7 @@ class AuthNAsync(ServiceBaseAsync):
348
352
  Returns:
349
353
  A PangeaResponse with credentials for a login session in the response.result field.
350
354
  Available response fields can be found in our
351
- [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/refresh).
355
+ [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/refresh-post).
352
356
 
353
357
  Examples:
354
358
  response = authn.client.session.refresh(
@@ -446,7 +450,7 @@ class AuthNAsync(ServiceBaseAsync):
446
450
  Returns:
447
451
  A PangeaResponse with a token and its information in the response.result field.
448
452
  Available response fields can be found in our
449
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/client/token/check).
453
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/client/token/check-post).
450
454
 
451
455
  Examples:
452
456
  response = authn.client.token_endpoints.check(
@@ -494,7 +498,7 @@ class AuthNAsync(ServiceBaseAsync):
494
498
  Returns:
495
499
  A PangeaResponse with a user and its information in the response.result field.
496
500
  Available response fields can be found in our
497
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/create).
501
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/create-post).
498
502
 
499
503
  Examples:
500
504
  response = authn.user.create(
@@ -563,7 +567,7 @@ class AuthNAsync(ServiceBaseAsync):
563
567
  Returns:
564
568
  A PangeaResponse with a pending user invitation in the response.result field.
565
569
  Available response fields can be found in our
566
- [API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite).
570
+ [API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite-post).
567
571
 
568
572
  Examples:
569
573
  response = authn.user.invite(
@@ -608,7 +612,7 @@ class AuthNAsync(ServiceBaseAsync):
608
612
  Returns:
609
613
  A PangeaResponse with a user and its information in the response.result field.
610
614
  Available response fields can be found in our
611
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/update).
615
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/update-post).
612
616
 
613
617
  Examples:
614
618
  response = authn.user.update(
@@ -652,7 +656,7 @@ class AuthNAsync(ServiceBaseAsync):
652
656
  Returns:
653
657
  A PangeaResponse with a list of users in the response.result field.
654
658
  Available response fields can be found in our
655
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/list).
659
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/list-post).
656
660
 
657
661
  Examples:
658
662
  response = authn.user.list()
@@ -705,7 +709,7 @@ class AuthNAsync(ServiceBaseAsync):
705
709
  Returns:
706
710
  A PangeaResponse with a list of pending user invitations in the response.result field.
707
711
  Available response fields can be found in our
708
- [API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite/list).
712
+ [API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite/list-post).
709
713
  Examples:
710
714
  response = authn.user.invites.list()
711
715
  """
@@ -809,7 +813,7 @@ class AuthNAsync(ServiceBaseAsync):
809
813
  Returns:
810
814
  A PangeaResponse with a list of authenticators in the response.result field.
811
815
  Available response fields can be found in our
812
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/authenticators/list).
816
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/authenticators/list-post).
813
817
 
814
818
  Examples:
815
819
  response = authn.user.authenticators.list(
@@ -852,7 +856,7 @@ class AuthNAsync(ServiceBaseAsync):
852
856
  Returns:
853
857
  A PangeaResponse with a user and its information in the response.result field.
854
858
  Available response fields can be found in our
855
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/get).
859
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/get-post).
856
860
 
857
861
  Examples:
858
862
  response = authn.user.profile.get(
@@ -888,7 +892,7 @@ class AuthNAsync(ServiceBaseAsync):
888
892
  Returns:
889
893
  A PangeaResponse with a user and its information in the response.result field.
890
894
  Available response fields can be found in our
891
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/update).
895
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/update-post).
892
896
 
893
897
  Examples:
894
898
  response = authn.user.profile.update(
@@ -982,7 +986,7 @@ class AuthNAsync(ServiceBaseAsync):
982
986
  Returns:
983
987
  A PangeaResponse with credentials for a login session in the response.result field.
984
988
  Available response fields can be found in our
985
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/complete).
989
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/complete-post).
986
990
 
987
991
  Examples:
988
992
  response = authn.flow.complete(
@@ -995,7 +999,10 @@ class AuthNAsync(ServiceBaseAsync):
995
999
  )
996
1000
 
997
1001
  async def restart(
998
- self, flow_id: str, choice: m.FlowChoice, data: m.FlowRestartData = {}
1002
+ self,
1003
+ flow_id: str,
1004
+ choice: m.FlowChoice,
1005
+ data: m.FlowRestartData = {}, # noqa: B006
999
1006
  ) -> PangeaResponse[m.FlowRestartResult]:
1000
1007
  """
1001
1008
  Restart a sign-up/sign-in flow
@@ -1013,7 +1020,7 @@ class AuthNAsync(ServiceBaseAsync):
1013
1020
  A PangeaResponse with information about next steps needed
1014
1021
  to complete a flow in the response.result field.
1015
1022
  Available response fields can be found in our
1016
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/restart).
1023
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/restart-post).
1017
1024
 
1018
1025
  Examples:
1019
1026
  response = authn.flow.restart(
@@ -1052,7 +1059,7 @@ class AuthNAsync(ServiceBaseAsync):
1052
1059
  A PangeaResponse with information about next steps needed
1053
1060
  to complete a flow in the response.result field.
1054
1061
  Available response fields can be found in our
1055
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/start).
1062
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/start-post).
1056
1063
 
1057
1064
  Examples:
1058
1065
  response = authn.flow.start(
@@ -1068,7 +1075,10 @@ class AuthNAsync(ServiceBaseAsync):
1068
1075
  return await self.request.post("v2/flow/start", m.FlowStartResult, data=input.model_dump(exclude_none=True))
1069
1076
 
1070
1077
  async def update(
1071
- self, flow_id: str, choice: m.FlowChoice, data: m.FlowUpdateData = {}
1078
+ self,
1079
+ flow_id: str,
1080
+ choice: m.FlowChoice,
1081
+ data: m.FlowUpdateData = {}, # noqa: B006
1072
1082
  ) -> PangeaResponse[m.FlowUpdateResult]:
1073
1083
  """
1074
1084
  Update a sign-up/sign-in flow
@@ -1086,7 +1096,7 @@ class AuthNAsync(ServiceBaseAsync):
1086
1096
  A PangeaResponse with information about next steps needed
1087
1097
  to complete a flow in the response.result field.
1088
1098
  Available response fields can be found in our
1089
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/update).
1099
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/update-post).
1090
1100
 
1091
1101
  Examples:
1092
1102
  response = authn.flow.update(
@@ -1133,7 +1143,7 @@ class AuthNAsync(ServiceBaseAsync):
1133
1143
  Returns:
1134
1144
  A PangeaResponse with a EULA object in the response.result field.
1135
1145
  Available response fields can be found in our
1136
- [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/create).
1146
+ [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/create-post).
1137
1147
 
1138
1148
  Examples:
1139
1149
  response = authn.agreements.create(
@@ -1200,7 +1210,7 @@ class AuthNAsync(ServiceBaseAsync):
1200
1210
  Returns:
1201
1211
  A PangeaResponse with a list of EULA objects in the response.result field.
1202
1212
  Available response fields can be found in our
1203
- [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/list).
1213
+ [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/list-post).
1204
1214
 
1205
1215
  Examples:
1206
1216
  response = authn.agreements.list()
@@ -1238,7 +1248,7 @@ class AuthNAsync(ServiceBaseAsync):
1238
1248
  Returns:
1239
1249
  A PangeaResponse with the updated EULA object in the response.result field.
1240
1250
  Available response fields can be found in our
1241
- [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/update).
1251
+ [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/update-post).
1242
1252
 
1243
1253
  Examples:
1244
1254
  response = authn.agreements.update(