pangea-sdk 6.3.0__tar.gz → 6.5.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 (63) hide show
  1. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/PKG-INFO +17 -18
  2. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/README.md +1 -2
  3. pangea_sdk-6.5.0/pangea/__init__.py +7 -0
  4. pangea_sdk-6.5.0/pangea/_constants.py +4 -0
  5. pangea_sdk-6.5.0/pangea/_typing.py +5 -0
  6. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/__init__.py +2 -1
  7. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/file_uploader.py +3 -2
  8. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/request.py +47 -10
  9. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/services/__init__.py +19 -2
  10. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/services/ai_guard.py +31 -29
  11. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/services/authn.py +25 -8
  12. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/services/base.py +21 -6
  13. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/services/file_scan.py +1 -1
  14. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/services/prompt_guard.py +3 -0
  15. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/config.py +4 -2
  16. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/file_uploader.py +4 -1
  17. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/request.py +72 -12
  18. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/response.py +5 -1
  19. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/__init__.py +19 -2
  20. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/ai_guard.py +84 -60
  21. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/audit/audit.py +2 -0
  22. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/audit/util.py +2 -0
  23. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/authn/authn.py +4 -5
  24. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/base.py +3 -0
  25. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/file_scan.py +3 -2
  26. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/prompt_guard.py +3 -0
  27. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/vault/vault.py +3 -0
  28. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pyproject.toml +21 -19
  29. pangea_sdk-6.3.0/pangea/__init__.py +0 -15
  30. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/services/audit.py +0 -0
  31. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/services/authz.py +0 -0
  32. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/services/embargo.py +0 -0
  33. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/services/intel.py +0 -0
  34. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/services/redact.py +0 -0
  35. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/services/sanitize.py +0 -0
  36. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/services/share.py +0 -0
  37. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/asyncio/services/vault.py +0 -0
  38. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/audit_logger.py +0 -0
  39. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/crypto/rsa.py +0 -0
  40. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/deep_verify.py +0 -0
  41. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/deprecated.py +0 -0
  42. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/dump_audit.py +0 -0
  43. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/exceptions.py +0 -0
  44. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/py.typed +0 -0
  45. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/audit/exceptions.py +0 -0
  46. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/audit/models.py +0 -0
  47. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/audit/signing.py +0 -0
  48. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/authn/models.py +0 -0
  49. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/authz.py +0 -0
  50. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/embargo.py +0 -0
  51. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/intel.py +0 -0
  52. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/redact.py +0 -0
  53. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/sanitize.py +0 -0
  54. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/share/file_format.py +0 -0
  55. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/share/share.py +0 -0
  56. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/vault/models/asymmetric.py +0 -0
  57. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/vault/models/common.py +0 -0
  58. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/vault/models/keys.py +0 -0
  59. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/vault/models/secret.py +0 -0
  60. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/services/vault/models/symmetric.py +0 -0
  61. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/tools.py +0 -0
  62. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/utils.py +0 -0
  63. {pangea_sdk-6.3.0 → pangea_sdk-6.5.0}/pangea/verify_audit.py +0 -0
@@ -1,24 +1,25 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: pangea-sdk
3
- Version: 6.3.0
3
+ Version: 6.5.0
4
4
  Summary: Pangea API SDK
5
- License: MIT
6
5
  Keywords: Pangea,SDK,Audit
7
6
  Author: Glenn Gallien
8
- Author-email: glenn.gallien@pangea.cloud
9
- Requires-Python: >=3.9.2,<4.0.0
7
+ Author-email: Glenn Gallien <glenn.gallien@pangea.cloud>
8
+ License-Expression: MIT
10
9
  Classifier: Topic :: Software Development
11
10
  Classifier: Topic :: Software Development :: Libraries
12
- Requires-Dist: aiohttp (>=3.12.14,<4.0.0)
13
- Requires-Dist: cryptography (>=45.0.5,<46.0.0)
14
- Requires-Dist: deprecated (>=1.2.18,<2.0.0)
15
- Requires-Dist: google-crc32c (>=1.7.1,<2.0.0)
16
- Requires-Dist: pydantic (>=2.11.7,<3.0.0)
17
- Requires-Dist: python-dateutil (>=2.9.0.post0,<3.0.0)
18
- Requires-Dist: requests (>=2.32.4,<3.0.0)
19
- Requires-Dist: requests-toolbelt (>=1.0.0,<2.0.0)
20
- Requires-Dist: typing-extensions (>=4.14.1,<5.0.0)
21
- Requires-Dist: yarl (>=1.20.1,<2.0.0)
11
+ Requires-Dist: aiohttp>=3.12.15,<4.0.0
12
+ Requires-Dist: cryptography>=45.0.6,<46.0.0
13
+ Requires-Dist: deprecated>=1.2.18,<2.0.0
14
+ Requires-Dist: google-crc32c>=1.7.1,<2.0.0
15
+ Requires-Dist: pydantic>=2.11.7,<3.0.0
16
+ Requires-Dist: python-dateutil>=2.9.0.post0,<3.0.0
17
+ Requires-Dist: requests>=2.32.4,<3.0.0
18
+ Requires-Dist: requests-toolbelt>=1.0.0,<2.0.0
19
+ Requires-Dist: typing-extensions>=4.14.1,<5.0.0
20
+ Requires-Dist: yarl>=1.20.1,<2.0.0
21
+ Requires-Python: >=3.9.2, <4.0.0
22
+ Project-URL: repository, https://github.com/pangeacyber/pangea-python
22
23
  Description-Content-Type: text/markdown
23
24
 
24
25
  <a href="https://pangea.cloud?utm_source=github&utm_medium=python-sdk" target="_blank" rel="noopener noreferrer">
@@ -116,8 +117,7 @@ The SDK supports the following configuration options via `PangeaConfig`:
116
117
  Use `base_url_template` for more control over the URL, such as setting
117
118
  service-specific paths. Defaults to `aws.us.pangea.cloud`.
118
119
  - `request_retries` — Number of retries on the initial request.
119
- - `request_backoff` — Backoff strategy passed to 'requests'.
120
- - `request_timeout` — Timeout used on initial request attempts.
120
+ - `request_backoff` — A backoff factor to apply between request attempts.
121
121
  - `poll_result_timeout` — Timeout used to poll results after 202 (in secs).
122
122
  - `queued_retry_enabled` — Enable queued request retry support.
123
123
  - `custom_user_agent` — Custom user agent to be used in the request headers.
@@ -243,4 +243,3 @@ It accepts multiple file formats:
243
243
  [Beta Examples]: https://github.com/pangeacyber/pangea-python/tree/beta/examples
244
244
  [Pangea Console]: https://console.pangea.cloud/
245
245
  [Secure Audit Log]: https://pangea.cloud/docs/audit
246
-
@@ -93,8 +93,7 @@ The SDK supports the following configuration options via `PangeaConfig`:
93
93
  Use `base_url_template` for more control over the URL, such as setting
94
94
  service-specific paths. Defaults to `aws.us.pangea.cloud`.
95
95
  - `request_retries` — Number of retries on the initial request.
96
- - `request_backoff` — Backoff strategy passed to 'requests'.
97
- - `request_timeout` — Timeout used on initial request attempts.
96
+ - `request_backoff` — A backoff factor to apply between request attempts.
98
97
  - `poll_result_timeout` — Timeout used to poll results after 202 (in secs).
99
98
  - `queued_retry_enabled` — Enable queued request retry support.
100
99
  - `custom_user_agent` — Custom user agent to be used in the request headers.
@@ -0,0 +1,7 @@
1
+ __version__ = "6.5.0"
2
+
3
+ from pangea.config import PangeaConfig
4
+ from pangea.file_uploader import FileUploader
5
+ from pangea.response import PangeaResponse, PangeaResponseResult, TransferMethod
6
+
7
+ __all__ = ("FileUploader", "PangeaConfig", "PangeaResponse", "PangeaResponseResult", "TransferMethod")
@@ -0,0 +1,4 @@
1
+ from __future__ import annotations
2
+
3
+ MAX_RETRY_DELAY = 8.0
4
+ RETRYABLE_HTTP_CODES = frozenset({500, 502, 503, 504})
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TypeVar
4
+
5
+ T = TypeVar("T")
@@ -1,2 +1,3 @@
1
- # ruff: noqa: F401
2
1
  from .file_uploader import FileUploaderAsync
2
+
3
+ __all__ = ("FileUploaderAsync",)
@@ -6,9 +6,10 @@ from __future__ import annotations
6
6
  import io
7
7
  import logging
8
8
 
9
+ from pangea import PangeaConfig, TransferMethod
9
10
  from pangea.asyncio.request import PangeaRequestAsync
10
- from pangea.request import PangeaConfig
11
- from pangea.response import TransferMethod
11
+
12
+ __all__ = ("FileUploaderAsync",)
12
13
 
13
14
 
14
15
  class FileUploaderAsync:
@@ -10,6 +10,7 @@ import asyncio
10
10
  import json
11
11
  import time
12
12
  from collections.abc import Iterable, Mapping
13
+ from random import random
13
14
  from typing import Dict, List, Optional, Sequence, Tuple, Type, Union, cast
14
15
 
15
16
  import aiohttp
@@ -19,10 +20,13 @@ from pydantic_core import to_jsonable_python
19
20
  from typing_extensions import Any, TypeAlias, TypeVar, override
20
21
 
21
22
  import pangea.exceptions as pe
23
+ from pangea._constants import MAX_RETRY_DELAY, RETRYABLE_HTTP_CODES
22
24
  from pangea.request import MultipartResponse, PangeaRequestBase
23
25
  from pangea.response import AttachedFile, PangeaResponse, PangeaResponseResult, ResponseStatus, TransferMethod
24
26
  from pangea.utils import default_encoder
25
27
 
28
+ __all__ = ("PangeaRequestAsync",)
29
+
26
30
  _FileName: TypeAlias = Union[str, None]
27
31
  _FileContent: TypeAlias = Union[str, bytes]
28
32
  _FileContentType: TypeAlias = str
@@ -462,13 +466,46 @@ class PangeaRequestAsync(PangeaRequestBase):
462
466
 
463
467
  @override
464
468
  def _init_session(self) -> aiohttp.ClientSession:
465
- # retry_config = Retry(
466
- # total=self.config.request_retries,
467
- # backoff_factor=self.config.request_backoff,
468
- # status_forcelist=[500, 502, 503, 504],
469
- # )
470
- # adapter = HTTPAdapter(max_retries=retry_config)
471
- # TODO: Add retry config
472
-
473
- session = aiohttp.ClientSession()
474
- return session
469
+ return aiohttp.ClientSession(middlewares=[self._retry_middleware])
470
+
471
+ def _calculate_retry_timeout(self, remaining_retries: int) -> float:
472
+ max_retries = self.config.request_retries
473
+ nb_retries = min(max_retries - remaining_retries, 1000)
474
+ sleep_seconds = min(self.config.request_backoff * pow(2.0, nb_retries), MAX_RETRY_DELAY)
475
+ jitter = 1 - 0.25 * random()
476
+ timeout = sleep_seconds * jitter
477
+ return max(timeout, 0)
478
+
479
+ async def _retry_middleware(
480
+ self, request: aiohttp.ClientRequest, handler: aiohttp.ClientHandlerType
481
+ ) -> aiohttp.ClientResponse:
482
+ max_retries = self.config.request_retries
483
+ request_ids = set[str]()
484
+ retries_taken = 0
485
+ for retries_taken in range(max_retries + 1):
486
+ remaining_retries = max_retries - retries_taken
487
+
488
+ if len(request_ids) > 0:
489
+ request.headers["X-Pangea-Retried-Request-Ids"] = ",".join(request_ids)
490
+
491
+ response = await handler(request)
492
+
493
+ request_id = response.headers.get("x-request-id")
494
+ if request_id:
495
+ request_ids.add(request_id)
496
+
497
+ if not response.ok and remaining_retries > 0 and self._should_retry(response):
498
+ await self._sleep_for_retry(retries_taken=retries_taken, max_retries=max_retries)
499
+ continue
500
+
501
+ break
502
+
503
+ return response
504
+
505
+ def _should_retry(self, response: aiohttp.ClientResponse) -> bool:
506
+ return response.status in RETRYABLE_HTTP_CODES
507
+
508
+ async def _sleep_for_retry(self, *, retries_taken: int, max_retries: int) -> None:
509
+ remaining_retries = max_retries - retries_taken
510
+ timeout = self._calculate_retry_timeout(remaining_retries)
511
+ await asyncio.sleep(timeout)
@@ -1,5 +1,3 @@
1
- # ruff: noqa: F401
2
-
3
1
  from .ai_guard import AIGuardAsync
4
2
  from .audit import AuditAsync
5
3
  from .authn import AuthNAsync
@@ -12,3 +10,22 @@ from .redact import RedactAsync
12
10
  from .sanitize import SanitizeAsync
13
11
  from .share import ShareAsync
14
12
  from .vault import VaultAsync
13
+
14
+ __all__ = (
15
+ "AIGuardAsync",
16
+ "AuditAsync",
17
+ "AuthNAsync",
18
+ "AuthZAsync",
19
+ "DomainIntelAsync",
20
+ "EmbargoAsync",
21
+ "FileIntelAsync",
22
+ "FileScanAsync",
23
+ "IpIntelAsync",
24
+ "PromptGuardAsync",
25
+ "RedactAsync",
26
+ "SanitizeAsync",
27
+ "ShareAsync",
28
+ "UrlIntelAsync",
29
+ "UserIntelAsync",
30
+ "VaultAsync",
31
+ )
@@ -15,11 +15,9 @@ class AIGuardAsync(ServiceBaseAsync):
15
15
  Provides methods to interact with Pangea's AI Guard service.
16
16
 
17
17
  Examples:
18
- from pangea import PangeaConfig
19
18
  from pangea.asyncio.services import AIGuardAsync
20
19
 
21
- config = PangeaConfig(domain="aws.us.pangea.cloud")
22
- ai_guard = AIGuardAsync(token="pangea_token", config=config)
20
+ ai_guard = AIGuardAsync(token="pangea_token")
23
21
  """
24
22
 
25
23
  service_name = "ai-guard"
@@ -39,11 +37,9 @@ class AIGuardAsync(ServiceBaseAsync):
39
37
  config_id: Configuration ID.
40
38
 
41
39
  Examples:
42
- from pangea import PangeaConfig
43
40
  from pangea.asyncio.services import AIGuardAsync
44
41
 
45
- config = PangeaConfig(domain="aws.us.pangea.cloud")
46
- ai_guard = AIGuardAsync(token="pangea_token", config=config)
42
+ ai_guard = AIGuardAsync(token="pangea_token")
47
43
  """
48
44
 
49
45
  super().__init__(token, config, logger_name, config_id)
@@ -53,29 +49,31 @@ class AIGuardAsync(ServiceBaseAsync):
53
49
  self,
54
50
  text: str,
55
51
  *,
56
- recipe: str | None = None,
57
52
  debug: bool | None = None,
58
- overrides: Overrides | None = None,
59
53
  log_fields: LogFields | None = None,
54
+ overrides: Overrides | None = None,
55
+ recipe: str | None = None,
60
56
  ) -> PangeaResponse[TextGuardResult]:
61
57
  """
62
- Text Guard for scanning LLM inputs and outputs
58
+ Guard LLM input and output text
63
59
 
64
- Analyze and redact text to avoid manipulation of the model, addition of
65
- malicious content, and other undesirable data transfers.
60
+ Detect, remove, or block malicious content and intent in LLM inputs and
61
+ outputs to prevent model manipulation and data leakage.
66
62
 
67
63
  OperationId: ai_guard_post_v1_text_guard
68
64
 
69
65
  Args:
70
66
  text: Text to be scanned by AI Guard for PII, sensitive data,
71
67
  malicious content, and other data types defined by the
72
- configuration. Supports processing up to 10KB of text.
73
- recipe: Recipe key of a configuration of data types and settings
74
- defined in the Pangea User Console. It specifies the rules that
75
- are to be applied to the text, such as defang malicious URLs.
68
+ configuration. Supports processing up to 20 KiB of text.
76
69
  debug: Setting this value to true will provide a detailed analysis
77
70
  of the text data
78
71
  log_field: Additional fields to include in activity log
72
+ overrides: Overrides flags. Note: This parameter has no effect when
73
+ the request is made by AIDR
74
+ recipe: Recipe key of a configuration of data types and settings
75
+ defined in the Pangea User Console. It specifies the rules that
76
+ are to be applied to the text, such as defang malicious URLs.
79
77
 
80
78
  Examples:
81
79
  response = await ai_guard.guard_text("text")
@@ -92,24 +90,26 @@ class AIGuardAsync(ServiceBaseAsync):
92
90
  log_fields: LogFields | None = None,
93
91
  ) -> PangeaResponse[TextGuardResult]:
94
92
  """
95
- Text Guard for scanning LLM inputs and outputs
93
+ Guard LLM input and output text
96
94
 
97
- Analyze and redact text to avoid manipulation of the model, addition of
98
- malicious content, and other undesirable data transfers.
95
+ Detect, remove, or block malicious content and intent in LLM inputs and
96
+ outputs to prevent model manipulation and data leakage.
99
97
 
100
98
  OperationId: ai_guard_post_v1_text_guard
101
99
 
102
100
  Args:
103
101
  messages: Structured messages data to be scanned by AI Guard for
104
102
  PII, sensitive data, malicious content, and other data types
105
- defined by the configuration. Supports processing up to 10KB of
106
- JSON text
107
- recipe: Recipe key of a configuration of data types and settings
108
- defined in the Pangea User Console. It specifies the rules that
109
- are to be applied to the text, such as defang malicious URLs.
103
+ defined by the configuration. Supports processing up to 20 KiB
104
+ of JSON text using Pangea message format.
110
105
  debug: Setting this value to true will provide a detailed analysis
111
106
  of the text data
112
107
  log_field: Additional fields to include in activity log
108
+ overrides: Overrides flags. Note: This parameter has no effect when
109
+ the request is made by AIDR
110
+ recipe: Recipe key of a configuration of data types and settings
111
+ defined in the Pangea User Console. It specifies the rules that
112
+ are to be applied to the text, such as defang malicious URLs.
113
113
 
114
114
  Examples:
115
115
  response = await ai_guard.guard_text(messages=[Message(role="user", content="hello world")])
@@ -126,10 +126,10 @@ class AIGuardAsync(ServiceBaseAsync):
126
126
  log_fields: LogFields | None = None,
127
127
  ) -> PangeaResponse[TextGuardResult]:
128
128
  """
129
- Text Guard for scanning LLM inputs and outputs
129
+ Guard LLM input and output text
130
130
 
131
- Analyze and redact text to avoid manipulation of the model, addition of
132
- malicious content, and other undesirable data transfers.
131
+ Detect, remove, or block malicious content and intent in LLM inputs and
132
+ outputs to prevent model manipulation and data leakage.
133
133
 
134
134
  OperationId: ai_guard_post_v1_text_guard
135
135
 
@@ -141,12 +141,14 @@ class AIGuardAsync(ServiceBaseAsync):
141
141
  PII, sensitive data, malicious content, and other data types
142
142
  defined by the configuration. Supports processing up to 10KB of
143
143
  JSON text
144
- recipe: Recipe key of a configuration of data types and settings
145
- defined in the Pangea User Console. It specifies the rules that
146
- are to be applied to the text, such as defang malicious URLs.
147
144
  debug: Setting this value to true will provide a detailed analysis
148
145
  of the text data
149
146
  log_field: Additional fields to include in activity log
147
+ overrides: Overrides flags. Note: This parameter has no effect when
148
+ the request is made by AIDR
149
+ recipe: Recipe key of a configuration of data types and settings
150
+ defined in the Pangea User Console. It specifies the rules that
151
+ are to be applied to the text, such as defang malicious URLs.
150
152
 
151
153
  Examples:
152
154
  response = await ai_guard.guard_text("text")
@@ -10,9 +10,9 @@ from collections.abc import Mapping
10
10
  from typing import Dict, List, Literal, Optional, Union
11
11
 
12
12
  import pangea.services.authn.models as m
13
+ from pangea import PangeaResponse, PangeaResponseResult
13
14
  from pangea.asyncio.services.base import ServiceBaseAsync
14
15
  from pangea.config import PangeaConfig
15
- from pangea.response import PangeaResponse, PangeaResponseResult
16
16
 
17
17
  __all__ = ["AuthNAsync"]
18
18
 
@@ -66,11 +66,18 @@ class AuthNAsync(ServiceBaseAsync):
66
66
  authn = AuthNAsync(token="pangea_token", config=config)
67
67
  """
68
68
  super().__init__(token, config, logger_name=logger_name)
69
- self.user = AuthNAsync.UserAsync(token, config, logger_name=logger_name)
70
- self.flow = AuthNAsync.FlowAsync(token, config, logger_name=logger_name)
69
+ self.agreements = AuthNAsync.AgreementsAsync(token, config, logger_name=logger_name)
71
70
  self.client = AuthNAsync.ClientAsync(token, config, logger_name=logger_name)
71
+ self.flow = AuthNAsync.FlowAsync(token, config, logger_name=logger_name)
72
72
  self.session = AuthNAsync.SessionAsync(token, config, logger_name=logger_name)
73
- self.agreements = AuthNAsync.AgreementsAsync(token, config, logger_name=logger_name)
73
+ self.user = AuthNAsync.UserAsync(token, config, logger_name=logger_name)
74
+
75
+ async def close(self) -> None:
76
+ await self.agreements.close()
77
+ await self.client.close()
78
+ await self.flow.close()
79
+ await self.session.close()
80
+ await self.user.close()
74
81
 
75
82
  class SessionAsync(ServiceBaseAsync):
76
83
  service_name = _SERVICE_NAME
@@ -179,10 +186,15 @@ class AuthNAsync(ServiceBaseAsync):
179
186
  logger_name: str = "pangea",
180
187
  ) -> None:
181
188
  super().__init__(token, config, logger_name=logger_name)
182
- self.session = AuthNAsync.ClientAsync.SessionAsync(token, config, logger_name=logger_name)
183
189
  self.password = AuthNAsync.ClientAsync.PasswordAsync(token, config, logger_name=logger_name)
190
+ self.session = AuthNAsync.ClientAsync.SessionAsync(token, config, logger_name=logger_name)
184
191
  self.token_endpoints = AuthNAsync.ClientAsync.TokenAsync(token, config, logger_name=logger_name)
185
192
 
193
+ async def close(self) -> None:
194
+ await self.password.close()
195
+ await self.session.close()
196
+ await self.token_endpoints.close()
197
+
186
198
  async def userinfo(self, code: str) -> PangeaResponse[m.ClientUserinfoResult]:
187
199
  """
188
200
  Get User (client token)
@@ -470,9 +482,14 @@ class AuthNAsync(ServiceBaseAsync):
470
482
  logger_name: str = "pangea",
471
483
  ) -> None:
472
484
  super().__init__(token, config, logger_name=logger_name)
473
- self.profile = AuthNAsync.UserAsync.ProfileAsync(token, config, logger_name=logger_name)
474
485
  self.authenticators = AuthNAsync.UserAsync.AuthenticatorsAsync(token, config, logger_name=logger_name)
475
486
  self.invites = AuthNAsync.UserAsync.InvitesAsync(token, config, logger_name=logger_name)
487
+ self.profile = AuthNAsync.UserAsync.ProfileAsync(token, config, logger_name=logger_name)
488
+
489
+ async def close(self) -> None:
490
+ await self.authenticators.close()
491
+ await self.invites.close()
492
+ await self.profile.close()
476
493
 
477
494
  async def create(
478
495
  self,
@@ -932,7 +949,7 @@ class AuthNAsync(ServiceBaseAsync):
932
949
  return await self.request.post(
933
950
  "v2/user/group/assign",
934
951
  data={"id": user_id, "group_ids": group_ids},
935
- result_class=m.PangeaResponseResult,
952
+ result_class=PangeaResponseResult,
936
953
  )
937
954
 
938
955
  async def remove(self, user_id: str, group_id: str) -> PangeaResponse[PangeaResponseResult]:
@@ -946,7 +963,7 @@ class AuthNAsync(ServiceBaseAsync):
946
963
  return await self.request.post(
947
964
  "v2/user/group/remove",
948
965
  data={"id": user_id, "group_id": group_id},
949
- result_class=m.PangeaResponseResult,
966
+ result_class=PangeaResponseResult,
950
967
  )
951
968
 
952
969
  async def list(self, user_id: str) -> PangeaResponse[m.GroupList]:
@@ -6,14 +6,20 @@
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
+ from types import TracebackType
9
10
  from typing import Dict, Optional, Type, Union
10
11
 
11
12
  from typing_extensions import override
12
13
 
14
+ from pangea import PangeaResponse, PangeaResponseResult
15
+ from pangea._typing import T
13
16
  from pangea.asyncio.request import PangeaRequestAsync
14
17
  from pangea.exceptions import AcceptedRequestException
15
- from pangea.response import AttachedFile, PangeaResponse, PangeaResponseResult
16
- from pangea.services.base import PangeaRequest, ServiceBase
18
+ from pangea.request import PangeaRequest
19
+ from pangea.response import AttachedFile
20
+ from pangea.services.base import ServiceBase
21
+
22
+ __all__ = ("ServiceBaseAsync",)
17
23
 
18
24
 
19
25
  class ServiceBaseAsync(ServiceBase):
@@ -85,8 +91,17 @@ class ServiceBaseAsync(ServiceBase):
85
91
  return await self.request.download_file(url=url, filename=filename)
86
92
 
87
93
  async def close(self):
94
+ """Close the underlying aiohttp client."""
95
+
88
96
  await self.request.session.close()
89
- # Loop over all attributes to check if they are derived from ServiceBaseAsync and close them
90
- for _, value in self.__dict__.items():
91
- if issubclass(type(value), ServiceBaseAsync):
92
- await value.close()
97
+
98
+ async def __aenter__(self: T) -> T:
99
+ return self
100
+
101
+ async def __aexit__(
102
+ self,
103
+ exc_type: type[BaseException] | None,
104
+ exc: BaseException | None,
105
+ exc_tb: TracebackType | None,
106
+ ) -> None:
107
+ await self.close()
@@ -11,9 +11,9 @@ import logging
11
11
  from typing import Dict, List, Optional, Tuple
12
12
 
13
13
  import pangea.services.file_scan as m
14
+ from pangea import PangeaConfig
14
15
  from pangea.asyncio.request import PangeaRequestAsync
15
16
  from pangea.asyncio.services.base import ServiceBaseAsync
16
- from pangea.request import PangeaConfig
17
17
  from pangea.response import PangeaResponse, TransferMethod
18
18
  from pangea.utils import FileUploadParams, get_file_upload_params
19
19
 
@@ -12,6 +12,9 @@ if TYPE_CHECKING:
12
12
  from pangea.response import PangeaResponse
13
13
 
14
14
 
15
+ __all__ = ("Message", "PromptGuardAsync")
16
+
17
+
15
18
  class PromptGuardAsync(ServiceBaseAsync):
16
19
  """Prompt Guard service client.
17
20
 
@@ -6,6 +6,8 @@ from typing import Any, Optional
6
6
 
7
7
  from pydantic import BaseModel, model_validator
8
8
 
9
+ __all__ = ("PangeaConfig",)
10
+
9
11
 
10
12
  class PangeaConfig(BaseModel):
11
13
  """Holds run time configuration information used by SDK components."""
@@ -34,12 +36,12 @@ class PangeaConfig(BaseModel):
34
36
 
35
37
  request_backoff: float = 0.5
36
38
  """
37
- Backoff strategy passed to 'requests'
39
+ A backoff factor to apply between request attempts.
38
40
  """
39
41
 
40
42
  request_timeout: int = 5
41
43
  """
42
- Timeout used on initial request attempts
44
+ Unused.
43
45
  """
44
46
 
45
47
  poll_result_timeout: int = 30
@@ -8,9 +8,12 @@ import io
8
8
  import logging
9
9
  from typing import Dict, Optional
10
10
 
11
- from pangea.request import PangeaConfig, PangeaRequest
11
+ from pangea.config import PangeaConfig
12
+ from pangea.request import PangeaRequest
12
13
  from pangea.response import TransferMethod
13
14
 
15
+ __all__ = ("FileUploader",)
16
+
14
17
 
15
18
  class FileUploader:
16
19
  def __init__(self):