pangea-sdk 3.7.1__tar.gz → 3.8.0__tar.gz

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 (46) hide show
  1. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/PKG-INFO +13 -8
  2. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/README.md +9 -5
  3. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/__init__.py +1 -1
  4. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/asyncio/request.py +11 -12
  5. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/asyncio/services/__init__.py +1 -0
  6. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/asyncio/services/audit.py +141 -10
  7. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/asyncio/services/authn.py +64 -48
  8. pangea_sdk-3.8.0/pangea/asyncio/services/authz.py +259 -0
  9. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/asyncio/services/intel.py +4 -4
  10. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/asyncio/services/redact.py +20 -1
  11. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/asyncio/services/vault.py +21 -4
  12. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/request.py +20 -17
  13. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/response.py +27 -16
  14. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/__init__.py +1 -0
  15. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/audit/audit.py +145 -13
  16. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/audit/models.py +40 -3
  17. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/authn/authn.py +20 -4
  18. pangea_sdk-3.8.0/pangea/services/authz.py +377 -0
  19. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/base.py +23 -6
  20. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/intel.py +2 -2
  21. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/redact.py +20 -1
  22. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/vault/vault.py +23 -6
  23. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/utils.py +2 -2
  24. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pyproject.toml +4 -3
  25. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/asyncio/services/base.py +0 -0
  26. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/asyncio/services/embargo.py +0 -0
  27. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/asyncio/services/file_scan.py +0 -0
  28. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/audit_logger.py +0 -0
  29. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/config.py +0 -0
  30. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/deep_verify.py +0 -0
  31. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/deprecated.py +0 -0
  32. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/dump_audit.py +0 -0
  33. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/exceptions.py +0 -0
  34. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/py.typed +0 -0
  35. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/audit/exceptions.py +0 -0
  36. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/audit/signing.py +0 -0
  37. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/audit/util.py +0 -0
  38. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/authn/models.py +0 -0
  39. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/embargo.py +0 -0
  40. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/file_scan.py +0 -0
  41. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/vault/models/asymmetric.py +0 -0
  42. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/vault/models/common.py +0 -0
  43. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/vault/models/secret.py +0 -0
  44. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/services/vault/models/symmetric.py +0 -0
  45. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/tools.py +0 -0
  46. {pangea_sdk-3.7.1 → pangea_sdk-3.8.0}/pangea/verify_audit.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pangea-sdk
3
- Version: 3.7.1
3
+ Version: 3.8.0
4
4
  Summary: Pangea API SDK
5
5
  Home-page: https://pangea.cloud/docs/sdk/python/
6
6
  License: MIT
@@ -18,13 +18,14 @@ Classifier: Topic :: Software Development
18
18
  Classifier: Topic :: Software Development :: Libraries
19
19
  Requires-Dist: aiohttp (>=3.8.6,<4.0.0)
20
20
  Requires-Dist: asyncio (>=3.4.3,<4.0.0)
21
- Requires-Dist: cryptography (>=42.0.5,<43.0.0)
21
+ Requires-Dist: cryptography (>=42.0.7,<43.0.0)
22
22
  Requires-Dist: deprecated (>=1.2.14,<2.0.0)
23
23
  Requires-Dist: google-crc32c (>=1.5.0,<2.0.0)
24
- Requires-Dist: pydantic (>=1.10.14,<2.0.0)
24
+ Requires-Dist: pydantic (>=1.10.15,<2.0.0)
25
25
  Requires-Dist: python-dateutil (>=2.9.0,<3.0.0)
26
26
  Requires-Dist: requests (>=2.31.0,<3.0.0)
27
27
  Requires-Dist: requests-toolbelt (>=1.0.0,<2.0.0)
28
+ Requires-Dist: typing-extensions (>=4.7.1,<5.0.0)
28
29
  Project-URL: Repository, https://github.com/pangeacyber/pangea-python/tree/main/packages/pangea-sdk
29
30
  Description-Content-Type: text/markdown
30
31
 
@@ -44,6 +45,8 @@ above.
44
45
 
45
46
  ## Installation
46
47
 
48
+ #### GA releases
49
+
47
50
  Via pip:
48
51
 
49
52
  ```bash
@@ -58,7 +61,7 @@ $ poetry add pangea-sdk
58
61
 
59
62
  <a name="beta-releases"></a>
60
63
 
61
- ### Beta releases
64
+ #### Beta releases
62
65
 
63
66
  Pre-release versions may be available with the `b` (beta) denotation in the
64
67
  version number. These releases serve to preview beta services and APIs. Per
@@ -68,19 +71,20 @@ compatibility guarantees as stable releases. [Beta changelog](https://github.com
68
71
  Via pip:
69
72
 
70
73
  ```bash
71
- $ pip3 install pangea-sdk==3.8.0b1
74
+ $ pip3 install pangea-sdk==3.8.0b2
72
75
  ```
73
76
 
74
77
  Via poetry:
75
78
 
76
79
  ```bash
77
- $ poetry add pangea-sdk==3.8.0b1
80
+ $ poetry add pangea-sdk==3.8.0b2
78
81
  ```
79
82
 
80
83
  ## Usage
81
84
 
82
85
  - [Documentation][]
83
- - [Examples][]
86
+ - [GA Examples][]
87
+ - [Beta Examples][]
84
88
 
85
89
  General usage would be to create a token for a service through the
86
90
  [Pangea Console][] and then construct an API client for that respective service.
@@ -224,7 +228,8 @@ It accepts multiple file formats:
224
228
 
225
229
 
226
230
  [Documentation]: https://pangea.cloud/docs/sdk/python/
227
- [Examples]: https://github.com/pangeacyber/pangea-python/tree/main/examples
231
+ [GA Examples]: https://github.com/pangeacyber/pangea-python/tree/main/examples
232
+ [Beta Examples]: https://github.com/pangeacyber/pangea-python/tree/beta/examples
228
233
  [Pangea Console]: https://console.pangea.cloud/
229
234
  [Slack]: https://pangea.cloud/join-slack/
230
235
  [Secure Audit Log]: https://pangea.cloud/docs/audit
@@ -14,6 +14,8 @@ above.
14
14
 
15
15
  ## Installation
16
16
 
17
+ #### GA releases
18
+
17
19
  Via pip:
18
20
 
19
21
  ```bash
@@ -28,7 +30,7 @@ $ poetry add pangea-sdk
28
30
 
29
31
  <a name="beta-releases"></a>
30
32
 
31
- ### Beta releases
33
+ #### Beta releases
32
34
 
33
35
  Pre-release versions may be available with the `b` (beta) denotation in the
34
36
  version number. These releases serve to preview beta services and APIs. Per
@@ -38,19 +40,20 @@ compatibility guarantees as stable releases. [Beta changelog](https://github.com
38
40
  Via pip:
39
41
 
40
42
  ```bash
41
- $ pip3 install pangea-sdk==3.8.0b1
43
+ $ pip3 install pangea-sdk==3.8.0b2
42
44
  ```
43
45
 
44
46
  Via poetry:
45
47
 
46
48
  ```bash
47
- $ poetry add pangea-sdk==3.8.0b1
49
+ $ poetry add pangea-sdk==3.8.0b2
48
50
  ```
49
51
 
50
52
  ## Usage
51
53
 
52
54
  - [Documentation][]
53
- - [Examples][]
55
+ - [GA Examples][]
56
+ - [Beta Examples][]
54
57
 
55
58
  General usage would be to create a token for a service through the
56
59
  [Pangea Console][] and then construct an API client for that respective service.
@@ -194,7 +197,8 @@ It accepts multiple file formats:
194
197
 
195
198
 
196
199
  [Documentation]: https://pangea.cloud/docs/sdk/python/
197
- [Examples]: https://github.com/pangeacyber/pangea-python/tree/main/examples
200
+ [GA Examples]: https://github.com/pangeacyber/pangea-python/tree/main/examples
201
+ [Beta Examples]: https://github.com/pangeacyber/pangea-python/tree/beta/examples
198
202
  [Pangea Console]: https://console.pangea.cloud/
199
203
  [Slack]: https://pangea.cloud/join-slack/
200
204
  [Secure Audit Log]: https://pangea.cloud/docs/audit
@@ -1,4 +1,4 @@
1
- __version__ = "3.7.1"
1
+ __version__ = "3.8.0"
2
2
 
3
3
  from pangea.asyncio.request import PangeaRequestAsync
4
4
  from pangea.config import PangeaConfig
@@ -8,12 +8,15 @@ from typing import Dict, List, Optional, Tuple, Type, Union
8
8
 
9
9
  import aiohttp
10
10
  from aiohttp import FormData
11
+ from typing_extensions import TypeVar
11
12
 
12
13
  import pangea.exceptions as pe
13
14
  from pangea.request import MultipartResponse, PangeaRequestBase
14
15
  from pangea.response import AttachedFile, PangeaResponse, PangeaResponseResult, ResponseStatus, TransferMethod
15
16
  from pangea.utils import default_encoder
16
17
 
18
+ TResult = TypeVar("TResult", bound=PangeaResponseResult, default=PangeaResponseResult)
19
+
17
20
 
18
21
  class PangeaRequestAsync(PangeaRequestBase):
19
22
  """An object that makes direct calls to Pangea Service APIs.
@@ -27,12 +30,12 @@ class PangeaRequestAsync(PangeaRequestBase):
27
30
  async def post(
28
31
  self,
29
32
  endpoint: str,
30
- result_class: Type[PangeaResponseResult],
33
+ result_class: Type[TResult],
31
34
  data: Union[str, Dict] = {},
32
35
  files: List[Tuple] = [],
33
36
  poll_result: bool = True,
34
37
  url: Optional[str] = None,
35
- ) -> PangeaResponse:
38
+ ) -> PangeaResponse[TResult]:
36
39
  """Makes the POST call to a Pangea Service endpoint.
37
40
 
38
41
  Args:
@@ -90,9 +93,7 @@ class PangeaRequestAsync(PangeaRequestBase):
90
93
 
91
94
  return self._check_response(pangea_response)
92
95
 
93
- async def get(
94
- self, path: str, result_class: Type[PangeaResponseResult], check_response: bool = True
95
- ) -> PangeaResponse[Type[PangeaResponseResult]]:
96
+ async def get(self, path: str, result_class: Type[TResult], check_response: bool = True) -> PangeaResponse[TResult]:
96
97
  """Makes the GET call to a Pangea Service endpoint.
97
98
 
98
99
  Args:
@@ -109,7 +110,7 @@ class PangeaRequestAsync(PangeaRequestBase):
109
110
 
110
111
  async with self.session.get(url, headers=self._headers()) as requests_response:
111
112
  await self._check_http_errors(requests_response)
112
- pangea_response = PangeaResponse( # type: ignore[var-annotated]
113
+ pangea_response = PangeaResponse(
113
114
  requests_response, result_class=result_class, json=await requests_response.json()
114
115
  )
115
116
 
@@ -130,11 +131,11 @@ class PangeaRequestAsync(PangeaRequestBase):
130
131
  raise pe.ServiceTemporarilyUnavailable(await resp.json())
131
132
 
132
133
  async def poll_result_by_id(
133
- self, request_id: str, result_class: Union[Type[PangeaResponseResult], Type[dict]], check_response: bool = True
134
- ):
134
+ self, request_id: str, result_class: Type[TResult], check_response: bool = True
135
+ ) -> PangeaResponse[TResult]:
135
136
  path = self._get_poll_path(request_id)
136
137
  self.logger.debug(json.dumps({"service": self.service, "action": "poll_result_once", "url": path}))
137
- return await self.get(path, result_class, check_response=check_response) # type: ignore[arg-type]
138
+ return await self.get(path, result_class, check_response=check_response)
138
139
 
139
140
  async def poll_result_once(self, response: PangeaResponse, check_response: bool = True):
140
141
  request_id = response.request_id
@@ -324,9 +325,7 @@ class PangeaRequestAsync(PangeaRequestBase):
324
325
  # Receive 202
325
326
  return await self._poll_presigned_url(accepted_exception.response)
326
327
 
327
- async def _poll_presigned_url(
328
- self, response: PangeaResponse[Type[PangeaResponseResult]]
329
- ) -> PangeaResponse[Type[PangeaResponseResult]]:
328
+ async def _poll_presigned_url(self, response: PangeaResponse[TResult]) -> PangeaResponse[TResult]:
330
329
  if response.http_status != 202:
331
330
  raise AttributeError("Response should be 202")
332
331
 
@@ -1,5 +1,6 @@
1
1
  from .audit import AuditAsync
2
2
  from .authn import AuthNAsync
3
+ from .authz import AuthZAsync
3
4
  from .embargo import EmbargoAsync
4
5
  from .file_scan import FileScanAsync
5
6
  from .intel import DomainIntelAsync, FileIntelAsync, IpIntelAsync, UrlIntelAsync, UserIntelAsync
@@ -1,11 +1,14 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+ from __future__ import annotations
4
+
3
5
  import datetime
4
6
  from typing import Any, Dict, List, Optional, Sequence, Union
5
7
 
6
8
  import pangea.exceptions as pexc
7
9
  from pangea.asyncio.services.base import ServiceBaseAsync
8
- from pangea.response import PangeaResponse
10
+ from pangea.config import PangeaConfig
11
+ from pangea.response import PangeaResponse, PangeaResponseResult
9
12
  from pangea.services.audit.audit import AuditBase
10
13
  from pangea.services.audit.exceptions import AuditException
11
14
  from pangea.services.audit.models import (
@@ -13,6 +16,7 @@ from pangea.services.audit.models import (
13
16
  DownloadRequest,
14
17
  DownloadResult,
15
18
  Event,
19
+ ExportRequest,
16
20
  LogBulkResult,
17
21
  LogResult,
18
22
  PublishedRoot,
@@ -56,14 +60,33 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
56
60
 
57
61
  def __init__(
58
62
  self,
59
- token,
60
- config=None,
63
+ token: str,
64
+ config: PangeaConfig | None = None,
61
65
  private_key_file: str = "",
62
- public_key_info: Dict[str, str] = {},
63
- tenant_id: Optional[str] = None,
64
- logger_name="pangea",
65
- config_id: Optional[str] = None,
66
- ):
66
+ public_key_info: dict[str, str] = {},
67
+ tenant_id: str | None = None,
68
+ logger_name: str = "pangea",
69
+ config_id: str | None = None,
70
+ ) -> None:
71
+ """
72
+ Audit client
73
+
74
+ Initializes a new Audit client.
75
+
76
+ Args:
77
+ token: Pangea API token.
78
+ config: Configuration.
79
+ private_key_file: Private key filepath.
80
+ public_key_info: Public key information.
81
+ tenant_id: Tenant ID.
82
+ logger_name: Logger name.
83
+ config_id: Configuration ID.
84
+
85
+ Examples:
86
+ config = PangeaConfig(domain="pangea_domain")
87
+ audit = AuditAsync(token="pangea_token", config=config)
88
+ """
89
+
67
90
  # FIXME: Temporary check to deprecate config_id from PangeaConfig.
68
91
  # Delete it when deprecate PangeaConfig.config_id
69
92
  if config_id and config is not None and config.config_id is not None:
@@ -402,6 +425,107 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
402
425
 
403
426
  return self.handle_results_response(response, verify_consistency, verify_events)
404
427
 
428
+ async def export(
429
+ self,
430
+ *,
431
+ format: DownloadFormat = DownloadFormat.CSV,
432
+ start: Optional[datetime.datetime] = None,
433
+ end: Optional[datetime.datetime] = None,
434
+ order: Optional[SearchOrder] = None,
435
+ order_by: Optional[str] = None,
436
+ verbose: bool = True,
437
+ ) -> PangeaResponse[PangeaResponseResult]:
438
+ """
439
+ Export from the audit log
440
+
441
+ Bulk export of data from the Secure Audit Log, with optional filtering.
442
+
443
+ OperationId: audit_post_v1_export
444
+
445
+ Args:
446
+ format: Format for the records.
447
+ start: The start of the time range to perform the search on.
448
+ end: The end of the time range to perform the search on. If omitted,
449
+ then all records up to the latest will be searched.
450
+ order: Specify the sort order of the response.
451
+ order_by: Name of column to sort the results by.
452
+ verbose: Whether or not to include the root hash of the tree and the
453
+ membership proof for each record.
454
+
455
+ Raises:
456
+ AuditException: If an audit based api exception happens
457
+ PangeaAPIException: If an API Error happens
458
+
459
+ Examples:
460
+ export_res = await audit.export(verbose=False)
461
+
462
+ # Export may take several dozens of minutes, so polling for the result
463
+ # should be done in a loop. That is omitted here for brevity's sake.
464
+ try:
465
+ await audit.poll_result(request_id=export_res.request_id)
466
+ except AcceptedRequestException:
467
+ # Retry later.
468
+
469
+ # Download the result when it's ready.
470
+ download_res = await audit.download_results(request_id=export_res.request_id)
471
+ download_res.result.dest_url
472
+ # => https://pangea-runtime.s3.amazonaws.com/audit/xxxxx/search_results_[...]
473
+ """
474
+ input = ExportRequest(
475
+ format=format,
476
+ start=start,
477
+ end=end,
478
+ order=order,
479
+ order_by=order_by,
480
+ verbose=verbose,
481
+ )
482
+ try:
483
+ return await self.request.post(
484
+ "v1/export", PangeaResponseResult, data=input.dict(exclude_none=True), poll_result=False
485
+ )
486
+ except pexc.AcceptedRequestException as e:
487
+ return e.response
488
+
489
+ async def log_stream(self, data: dict) -> PangeaResponse[PangeaResponseResult]:
490
+ """
491
+ Log streaming endpoint
492
+
493
+ This API allows 3rd party vendors (like Auth0) to stream events to this
494
+ endpoint where the structure of the payload varies across different
495
+ vendors.
496
+
497
+ OperationId: audit_post_v1_log_stream
498
+
499
+ Args:
500
+ data: Event data. The exact schema of this will vary by vendor.
501
+
502
+ Raises:
503
+ AuditException: If an audit based api exception happens
504
+ PangeaAPIException: If an API Error happens
505
+
506
+ Examples:
507
+ data = {
508
+ "logs": [
509
+ {
510
+ "log_id": "some log ID",
511
+ "data": {
512
+ "date": "2024-03-29T17:26:50.193Z",
513
+ "type": "sapi",
514
+ "description": "Create a log stream",
515
+ "client_id": "some client ID",
516
+ "ip": "127.0.0.1",
517
+ "user_agent": "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0",
518
+ "user_id": "some user ID",
519
+ },
520
+ }
521
+ # ...
522
+ ]
523
+ }
524
+
525
+ response = await audit.log_stream(data)
526
+ """
527
+ return await self.request.post("v1/log_stream", PangeaResponseResult, data=data)
528
+
405
529
  async def root(self, tree_size: Optional[int] = None) -> PangeaResponse[RootResult]:
406
530
  """
407
531
  Tamperproof verification
@@ -427,7 +551,10 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
427
551
  return await self.request.post("v1/root", RootResult, data=input.dict(exclude_none=True))
428
552
 
429
553
  async def download_results(
430
- self, result_id: str, format: Optional[DownloadFormat] = None
554
+ self,
555
+ result_id: Optional[str] = None,
556
+ format: DownloadFormat = DownloadFormat.CSV,
557
+ request_id: Optional[str] = None,
431
558
  ) -> PangeaResponse[DownloadResult]:
432
559
  """
433
560
  Download search results
@@ -439,6 +566,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
439
566
  Args:
440
567
  result_id: ID returned by the search API.
441
568
  format: Format for the records.
569
+ request_id: ID returned by the export API.
442
570
 
443
571
  Returns:
444
572
  URL where search results can be downloaded.
@@ -454,7 +582,10 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
454
582
  )
455
583
  """
456
584
 
457
- input = DownloadRequest(result_id=result_id, format=format)
585
+ if request_id is None and result_id is None:
586
+ raise ValueError("must pass one of `request_id` or `result_id`")
587
+
588
+ input = DownloadRequest(request_id=request_id, result_id=result_id, format=format)
458
589
  return await self.request.post("v1/download_results", DownloadResult, data=input.dict(exclude_none=True))
459
590
 
460
591
  async def update_published_roots(self, result: SearchResultOutput):
@@ -1,10 +1,12 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+ from __future__ import annotations
3
4
 
4
5
  from typing import Dict, List, Optional, Union
5
6
 
6
7
  import pangea.services.authn.models as m
7
8
  from pangea.asyncio.services.base import ServiceBaseAsync
9
+ from pangea.config import PangeaConfig
8
10
  from pangea.response import PangeaResponse
9
11
 
10
12
  SERVICE_NAME = "authn"
@@ -37,10 +39,24 @@ class AuthNAsync(ServiceBaseAsync):
37
39
 
38
40
  def __init__(
39
41
  self,
40
- token,
41
- config=None,
42
- logger_name="pangea",
43
- ):
42
+ token: str,
43
+ config: PangeaConfig | None = None,
44
+ logger_name: str = "pangea",
45
+ ) -> None:
46
+ """
47
+ AuthN client
48
+
49
+ Initializes a new AuthN client.
50
+
51
+ Args:
52
+ token: Pangea API token.
53
+ config: Configuration.
54
+ logger_name: Logger name.
55
+
56
+ Examples:
57
+ config = PangeaConfig(domain="pangea_domain")
58
+ authn = AuthNAsync(token="pangea_token", config=config)
59
+ """
44
60
  super().__init__(token, config, logger_name=logger_name)
45
61
  self.user = AuthNAsync.UserAsync(token, config, logger_name=logger_name)
46
62
  self.flow = AuthNAsync.FlowAsync(token, config, logger_name=logger_name)
@@ -53,10 +69,10 @@ class AuthNAsync(ServiceBaseAsync):
53
69
 
54
70
  def __init__(
55
71
  self,
56
- token,
57
- config=None,
58
- logger_name="pangea",
59
- ):
72
+ token: str,
73
+ config: PangeaConfig | None = None,
74
+ logger_name: str = "pangea",
75
+ ) -> None:
60
76
  super().__init__(token, config, logger_name=logger_name)
61
77
 
62
78
  async def invalidate(self, session_id: str) -> PangeaResponse[m.SessionInvalidateResult]:
@@ -148,10 +164,10 @@ class AuthNAsync(ServiceBaseAsync):
148
164
 
149
165
  def __init__(
150
166
  self,
151
- token,
152
- config=None,
153
- logger_name="pangea",
154
- ):
167
+ token: str,
168
+ config: PangeaConfig | None = None,
169
+ logger_name: str = "pangea",
170
+ ) -> None:
155
171
  super().__init__(token, config, logger_name=logger_name)
156
172
  self.session = AuthNAsync.ClientAsync.SessionAsync(token, config, logger_name=logger_name)
157
173
  self.password = AuthNAsync.ClientAsync.PasswordAsync(token, config, logger_name=logger_name)
@@ -208,10 +224,10 @@ class AuthNAsync(ServiceBaseAsync):
208
224
 
209
225
  def __init__(
210
226
  self,
211
- token,
212
- config=None,
213
- logger_name="pangea",
214
- ):
227
+ token: str,
228
+ config: PangeaConfig | None = None,
229
+ logger_name: str = "pangea",
230
+ ) -> None:
215
231
  super().__init__(token, config, logger_name=logger_name)
216
232
 
217
233
  async def invalidate(self, token: str, session_id: str) -> PangeaResponse[m.ClientSessionInvalidateResult]:
@@ -343,10 +359,10 @@ class AuthNAsync(ServiceBaseAsync):
343
359
 
344
360
  def __init__(
345
361
  self,
346
- token,
347
- config=None,
348
- logger_name="pangea",
349
- ):
362
+ token: str,
363
+ config: PangeaConfig | None = None,
364
+ logger_name: str = "pangea",
365
+ ) -> None:
350
366
  super().__init__(token, config, logger_name=logger_name)
351
367
 
352
368
  async def change(
@@ -384,10 +400,10 @@ class AuthNAsync(ServiceBaseAsync):
384
400
 
385
401
  def __init__(
386
402
  self,
387
- token,
388
- config=None,
389
- logger_name="pangea",
390
- ):
403
+ token: str,
404
+ config: PangeaConfig | None = None,
405
+ logger_name: str = "pangea",
406
+ ) -> None:
391
407
  super().__init__(token, config, logger_name=logger_name)
392
408
 
393
409
  async def check(self, token: str) -> PangeaResponse[m.ClientTokenCheckResult]:
@@ -421,10 +437,10 @@ class AuthNAsync(ServiceBaseAsync):
421
437
 
422
438
  def __init__(
423
439
  self,
424
- token,
425
- config=None,
426
- logger_name="pangea",
427
- ):
440
+ token: str,
441
+ config: PangeaConfig | None = None,
442
+ logger_name: str = "pangea",
443
+ ) -> None:
428
444
  super().__init__(token, config, logger_name=logger_name)
429
445
  self.profile = AuthNAsync.UserAsync.ProfileAsync(token, config, logger_name=logger_name)
430
446
  self.authenticators = AuthNAsync.UserAsync.AuthenticatorsAsync(token, config, logger_name=logger_name)
@@ -615,10 +631,10 @@ class AuthNAsync(ServiceBaseAsync):
615
631
 
616
632
  def __init__(
617
633
  self,
618
- token,
619
- config=None,
620
- logger_name="pangea",
621
- ):
634
+ token: str,
635
+ config: PangeaConfig | None = None,
636
+ logger_name: str = "pangea",
637
+ ) -> None:
622
638
  super().__init__(token, config, logger_name=logger_name)
623
639
 
624
640
  async def list(
@@ -687,10 +703,10 @@ class AuthNAsync(ServiceBaseAsync):
687
703
 
688
704
  def __init__(
689
705
  self,
690
- token,
691
- config=None,
692
- logger_name="pangea",
693
- ):
706
+ token: str,
707
+ config: PangeaConfig | None = None,
708
+ logger_name: str = "pangea",
709
+ ) -> None:
694
710
  super().__init__(token, config, logger_name=logger_name)
695
711
 
696
712
  async def delete(
@@ -758,10 +774,10 @@ class AuthNAsync(ServiceBaseAsync):
758
774
 
759
775
  def __init__(
760
776
  self,
761
- token,
762
- config=None,
763
- logger_name="pangea",
764
- ):
777
+ token: str,
778
+ config: PangeaConfig | None = None,
779
+ logger_name: str = "pangea",
780
+ ) -> None:
765
781
  super().__init__(token, config, logger_name=logger_name)
766
782
 
767
783
  async def get(
@@ -838,10 +854,10 @@ class AuthNAsync(ServiceBaseAsync):
838
854
 
839
855
  def __init__(
840
856
  self,
841
- token,
842
- config=None,
843
- logger_name="pangea",
844
- ):
857
+ token: str,
858
+ config: PangeaConfig | None = None,
859
+ logger_name: str = "pangea",
860
+ ) -> None:
845
861
  super().__init__(token, config, logger_name=logger_name)
846
862
 
847
863
  async def complete(self, flow_id: str) -> PangeaResponse[m.FlowCompleteResult]:
@@ -978,10 +994,10 @@ class AuthNAsync(ServiceBaseAsync):
978
994
 
979
995
  def __init__(
980
996
  self,
981
- token,
982
- config=None,
983
- logger_name="pangea",
984
- ):
997
+ token: str,
998
+ config: PangeaConfig | None = None,
999
+ logger_name: str = "pangea",
1000
+ ) -> None:
985
1001
  super().__init__(token, config, logger_name=logger_name)
986
1002
 
987
1003
  async def create(