pangea-sdk 6.5.0__tar.gz → 6.6.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.5.0 → pangea_sdk-6.6.0}/PKG-INFO +3 -3
  2. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/__init__.py +1 -1
  3. pangea_sdk-6.6.0/pangea/_typing.py +30 -0
  4. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/services/ai_guard.py +29 -4
  5. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/services/intel.py +160 -95
  6. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/ai_guard.py +91 -13
  7. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/intel.py +187 -252
  8. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pyproject.toml +5 -5
  9. pangea_sdk-6.5.0/pangea/_typing.py +0 -5
  10. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/README.md +0 -0
  11. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/_constants.py +0 -0
  12. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/__init__.py +0 -0
  13. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/file_uploader.py +0 -0
  14. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/request.py +0 -0
  15. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/services/__init__.py +0 -0
  16. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/services/audit.py +0 -0
  17. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/services/authn.py +0 -0
  18. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/services/authz.py +0 -0
  19. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/services/base.py +0 -0
  20. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/services/embargo.py +0 -0
  21. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/services/file_scan.py +0 -0
  22. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/services/prompt_guard.py +0 -0
  23. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/services/redact.py +0 -0
  24. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/services/sanitize.py +0 -0
  25. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/services/share.py +0 -0
  26. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/asyncio/services/vault.py +0 -0
  27. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/audit_logger.py +0 -0
  28. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/config.py +0 -0
  29. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/crypto/rsa.py +0 -0
  30. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/deep_verify.py +0 -0
  31. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/deprecated.py +0 -0
  32. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/dump_audit.py +0 -0
  33. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/exceptions.py +0 -0
  34. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/file_uploader.py +0 -0
  35. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/py.typed +0 -0
  36. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/request.py +0 -0
  37. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/response.py +0 -0
  38. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/__init__.py +0 -0
  39. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/audit/audit.py +0 -0
  40. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/audit/exceptions.py +0 -0
  41. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/audit/models.py +0 -0
  42. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/audit/signing.py +0 -0
  43. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/audit/util.py +0 -0
  44. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/authn/authn.py +0 -0
  45. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/authn/models.py +0 -0
  46. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/authz.py +0 -0
  47. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/base.py +0 -0
  48. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/embargo.py +0 -0
  49. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/file_scan.py +0 -0
  50. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/prompt_guard.py +0 -0
  51. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/redact.py +0 -0
  52. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/sanitize.py +0 -0
  53. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/share/file_format.py +0 -0
  54. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/share/share.py +0 -0
  55. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/vault/models/asymmetric.py +0 -0
  56. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/vault/models/common.py +0 -0
  57. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/vault/models/keys.py +0 -0
  58. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/vault/models/secret.py +0 -0
  59. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/vault/models/symmetric.py +0 -0
  60. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/services/vault/vault.py +0 -0
  61. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/tools.py +0 -0
  62. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/utils.py +0 -0
  63. {pangea_sdk-6.5.0 → pangea_sdk-6.6.0}/pangea/verify_audit.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pangea-sdk
3
- Version: 6.5.0
3
+ Version: 6.6.0
4
4
  Summary: Pangea API SDK
5
5
  Keywords: Pangea,SDK,Audit
6
6
  Author: Glenn Gallien
@@ -14,9 +14,9 @@ Requires-Dist: deprecated>=1.2.18,<2.0.0
14
14
  Requires-Dist: google-crc32c>=1.7.1,<2.0.0
15
15
  Requires-Dist: pydantic>=2.11.7,<3.0.0
16
16
  Requires-Dist: python-dateutil>=2.9.0.post0,<3.0.0
17
- Requires-Dist: requests>=2.32.4,<3.0.0
17
+ Requires-Dist: requests>=2.32.5,<3.0.0
18
18
  Requires-Dist: requests-toolbelt>=1.0.0,<2.0.0
19
- Requires-Dist: typing-extensions>=4.14.1,<5.0.0
19
+ Requires-Dist: typing-extensions>=4.15.0,<5.0.0
20
20
  Requires-Dist: yarl>=1.20.1,<2.0.0
21
21
  Requires-Python: >=3.9.2, <4.0.0
22
22
  Project-URL: repository, https://github.com/pangeacyber/pangea-python
@@ -1,4 +1,4 @@
1
- __version__ = "6.5.0"
1
+ __version__ = "6.6.0"
2
2
 
3
3
  from pangea.config import PangeaConfig
4
4
  from pangea.file_uploader import FileUploader
@@ -0,0 +1,30 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Iterator, Sequence
4
+
5
+ from typing_extensions import Any, Protocol, SupportsIndex, TypeVar, overload
6
+
7
+ T = TypeVar("T")
8
+ T_co = TypeVar("T_co", covariant=True)
9
+
10
+
11
+ class SequenceNotStr(Protocol[T_co]):
12
+ """Sequence-like object that isn't str or bytes."""
13
+
14
+ @overload
15
+ def __getitem__(self, index: SupportsIndex, /) -> T_co: ...
16
+
17
+ @overload
18
+ def __getitem__(self, index: slice, /) -> Sequence[T_co]: ...
19
+
20
+ def __contains__(self, value: object, /) -> bool: ...
21
+
22
+ def __len__(self) -> int: ...
23
+
24
+ def __iter__(self) -> Iterator[T_co]: ...
25
+
26
+ def index(self, value: Any, start: int = ..., stop: int = ..., /) -> int: ...
27
+
28
+ def count(self, value: Any, /) -> int: ...
29
+
30
+ def __reversed__(self) -> Iterator[T_co]: ...
@@ -6,7 +6,15 @@ from typing import overload
6
6
  from pangea.asyncio.services.base import ServiceBaseAsync
7
7
  from pangea.config import PangeaConfig
8
8
  from pangea.response import PangeaResponse
9
- from pangea.services.ai_guard import LogFields, Message, Overrides, TextGuardResult
9
+ from pangea.services.ai_guard import (
10
+ LogFields,
11
+ McpToolsMessage,
12
+ Message,
13
+ Overrides,
14
+ TextGuardResult,
15
+ get_relevant_content,
16
+ patch_messages,
17
+ )
10
18
 
11
19
 
12
20
  class AIGuardAsync(ServiceBaseAsync):
@@ -83,11 +91,12 @@ class AIGuardAsync(ServiceBaseAsync):
83
91
  async def guard_text(
84
92
  self,
85
93
  *,
86
- messages: Sequence[Message],
94
+ messages: Sequence[Message | McpToolsMessage],
87
95
  recipe: str | None = None,
88
96
  debug: bool | None = None,
89
97
  overrides: Overrides | None = None,
90
98
  log_fields: LogFields | None = None,
99
+ only_relevant_content: bool = False,
91
100
  ) -> PangeaResponse[TextGuardResult]:
92
101
  """
93
102
  Guard LLM input and output text
@@ -110,6 +119,8 @@ class AIGuardAsync(ServiceBaseAsync):
110
119
  recipe: Recipe key of a configuration of data types and settings
111
120
  defined in the Pangea User Console. It specifies the rules that
112
121
  are to be applied to the text, such as defang malicious URLs.
122
+ only_relevant_content: Whether or not to only send relevant content
123
+ to AI Guard.
113
124
 
114
125
  Examples:
115
126
  response = await ai_guard.guard_text(messages=[Message(role="user", content="hello world")])
@@ -119,11 +130,12 @@ class AIGuardAsync(ServiceBaseAsync):
119
130
  self,
120
131
  text: str | None = None,
121
132
  *,
122
- messages: Sequence[Message] | None = None,
133
+ messages: Sequence[Message | McpToolsMessage] | None = None,
123
134
  recipe: str | None = None,
124
135
  debug: bool | None = None,
125
136
  overrides: Overrides | None = None,
126
137
  log_fields: LogFields | None = None,
138
+ only_relevant_content: bool = False,
127
139
  ) -> PangeaResponse[TextGuardResult]:
128
140
  """
129
141
  Guard LLM input and output text
@@ -149,6 +161,8 @@ class AIGuardAsync(ServiceBaseAsync):
149
161
  recipe: Recipe key of a configuration of data types and settings
150
162
  defined in the Pangea User Console. It specifies the rules that
151
163
  are to be applied to the text, such as defang malicious URLs.
164
+ only_relevant_content: Whether or not to only send relevant content
165
+ to AI Guard.
152
166
 
153
167
  Examples:
154
168
  response = await ai_guard.guard_text("text")
@@ -157,7 +171,11 @@ class AIGuardAsync(ServiceBaseAsync):
157
171
  if text is not None and messages is not None:
158
172
  raise ValueError("Exactly one of `text` or `messages` must be given")
159
173
 
160
- return await self.request.post(
174
+ if only_relevant_content and messages is not None:
175
+ original_messages = messages
176
+ messages, original_indices = get_relevant_content(messages)
177
+
178
+ response = await self.request.post(
161
179
  "v1/text/guard",
162
180
  TextGuardResult,
163
181
  data={
@@ -169,3 +187,10 @@ class AIGuardAsync(ServiceBaseAsync):
169
187
  "log_fields": log_fields,
170
188
  },
171
189
  )
190
+
191
+ if only_relevant_content and response.result and response.result.prompt_messages:
192
+ response.result.prompt_messages = patch_messages(
193
+ original_messages, original_indices, response.result.prompt_messages
194
+ ) # type: ignore[assignment]
195
+
196
+ return response
@@ -9,6 +9,7 @@ import hashlib
9
9
  from typing import List, Literal, Optional
10
10
 
11
11
  import pangea.services.intel as m
12
+ from pangea._typing import SequenceNotStr
12
13
  from pangea.asyncio.services.base import ServiceBaseAsync
13
14
  from pangea.response import PangeaResponse
14
15
  from pangea.utils import hash_256_filepath
@@ -320,33 +321,26 @@ class DomainIntelAsync(ServiceBaseAsync):
320
321
 
321
322
 
322
323
  class IpIntelAsync(ServiceBaseAsync):
323
- """IP Intel service client
324
-
325
- Provides methods to interact with [Pangea IP Intel Service](/docs/api/ip-intel)
326
-
327
- The following information is needed:
328
- PANGEA_TOKEN - service token which can be found on the Pangea User
329
- Console at [https://console.pangea.cloud/project/tokens](https://console.pangea.cloud/project/tokens)
324
+ """
325
+ IP Intel service client
330
326
 
331
327
  Examples:
332
328
  import os
333
329
 
334
- # Pangea SDK
335
- from pangea.config import PangeaConfig
336
- from pangea.services import IpIntel
330
+ from pangea.asyncio.services import IpIntelAsync
337
331
 
338
- PANGEA_TOKEN = os.getenv("PANGEA_TOKEN")
339
-
340
- ip_intel_config = PangeaConfig(domain="pangea.cloud")
341
-
342
- # Setup Pangea IP Intel service
343
- ip_intel = IpIntel(token=PANGEA_TOKEN, config=ip_intel_config)
332
+ ip_intel = IpIntelAsync(token="my_api_token")
344
333
  """
345
334
 
346
335
  service_name = "ip-intel"
347
336
 
348
337
  async def reputation(
349
- self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
338
+ self,
339
+ ip: str,
340
+ *,
341
+ verbose: bool | None = None,
342
+ raw: bool | None = None,
343
+ provider: Literal["crowdstrike", "cymru"] | None = None,
350
344
  ) -> PangeaResponse[m.IPReputationResult]:
351
345
  """
352
346
  Reputation
@@ -356,10 +350,10 @@ class IpIntelAsync(ServiceBaseAsync):
356
350
  OperationId: ip_intel_post_v1_reputation
357
351
 
358
352
  Args:
359
- ip (str): The IP to be looked up
360
- verbose (bool, optional): Echo the API parameters in the response
361
- raw (bool, optional): Include raw data from this provider
362
- provider (str, optional): Use reputation data from this provider
353
+ ip: The IP to be looked up
354
+ verbose: Echo the API parameters in the response
355
+ raw: Include raw data from this provider
356
+ provider: Use reputation data from this provider
363
357
 
364
358
  Raises:
365
359
  PangeaAPIException: If an API Error happens
@@ -374,24 +368,30 @@ class IpIntelAsync(ServiceBaseAsync):
374
368
  provider="crowdstrike",
375
369
  )
376
370
  """
377
- input = m.IPReputationRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
378
- return await self.request.post("v1/reputation", m.IPReputationResult, data=input.model_dump(exclude_none=True))
371
+ return await self.request.post(
372
+ "v1/reputation", m.IPReputationResult, data={"ip": ip, "verbose": verbose, "raw": raw, "provider": provider}
373
+ )
379
374
 
380
375
  async def reputation_bulk(
381
- self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
376
+ self,
377
+ ips: SequenceNotStr[str],
378
+ *,
379
+ verbose: bool | None = None,
380
+ raw: bool | None = None,
381
+ provider: Literal["crowdstrike", "cymru"] | None = None,
382
382
  ) -> PangeaResponse[m.IPReputationBulkResult]:
383
383
  """
384
384
  Reputation
385
385
 
386
386
  Retrieve a reputation score for an IP address from a provider, including an optional detailed report.
387
387
 
388
- OperationId: FIXME:
388
+ OperationId: ip_intel_post_v2_reputation
389
389
 
390
390
  Args:
391
- ips (List[str]): The IP list to be looked up
392
- verbose (bool, optional): Echo the API parameters in the response
393
- raw (bool, optional): Include raw data from this provider
394
- provider (str, optional): Use reputation data from this provider
391
+ ips: The IP to be looked up
392
+ verbose: Echo the API parameters in the response
393
+ raw: Include raw data from this provider
394
+ provider: Use reputation data from this provider
395
395
 
396
396
  Raises:
397
397
  PangeaAPIException: If an API Error happens
@@ -403,13 +403,19 @@ class IpIntelAsync(ServiceBaseAsync):
403
403
  Examples:
404
404
  FIXME:
405
405
  """
406
- input = m.IPReputationBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
407
406
  return await self.request.post(
408
- "v2/reputation", m.IPReputationBulkResult, data=input.model_dump(exclude_none=True)
407
+ "v2/reputation",
408
+ m.IPReputationBulkResult,
409
+ data={"ips": ips, "verbose": verbose, "raw": raw, "provider": provider},
409
410
  )
410
411
 
411
412
  async def geolocate(
412
- self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
413
+ self,
414
+ ip: str,
415
+ *,
416
+ verbose: bool | None = None,
417
+ raw: bool | None = None,
418
+ provider: Literal["digitalenvoy", "digitalelement"] | None = None,
413
419
  ) -> PangeaResponse[m.IPGeolocateResult]:
414
420
  """
415
421
  Geolocate
@@ -419,10 +425,10 @@ class IpIntelAsync(ServiceBaseAsync):
419
425
  OperationId: ip_intel_post_v1_geolocate
420
426
 
421
427
  Args:
422
- ips (List[str]): IP address' list to be geolocated
423
- provider (str, optional): Use geolocation data from this provider ("digitalelement"). Default provider defined by the configuration.
424
- verbose (bool, optional): Echo the API parameters in the response
425
- raw (bool, optional): Include raw data from this provider
428
+ ip: The IP to be looked up
429
+ verbose: Echo the API parameters in the response
430
+ raw: Include raw data from this provider
431
+ provider: Use location data from this provider
426
432
 
427
433
  Raises:
428
434
  PangeaAPIException: If an API Error happens
@@ -437,24 +443,30 @@ class IpIntelAsync(ServiceBaseAsync):
437
443
  provider="digitalelement",
438
444
  )
439
445
  """
440
- input = m.IPGeolocateRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
441
- return await self.request.post("v1/geolocate", m.IPGeolocateResult, data=input.model_dump(exclude_none=True))
446
+ return await self.request.post(
447
+ "v1/geolocate", m.IPGeolocateResult, data={"ip": ip, "verbose": verbose, "raw": raw, "provider": provider}
448
+ )
442
449
 
443
450
  async def geolocate_bulk(
444
- self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
451
+ self,
452
+ ips: SequenceNotStr[str],
453
+ *,
454
+ verbose: bool | None = None,
455
+ raw: bool | None = None,
456
+ provider: Literal["digitalenvoy", "digitalelement"] | None = None,
445
457
  ) -> PangeaResponse[m.IPGeolocateBulkResult]:
446
458
  """
447
459
  Geolocate
448
460
 
449
461
  Retrieve information about the location of an IP address.
450
462
 
451
- OperationId: FIXME:
463
+ OperationId: ip_intel_post_v2_geolocate
452
464
 
453
465
  Args:
454
- ips (List[str]): IP addresses list to be geolocated
455
- provider (str, optional): Use geolocation data from this provider ("digitalelement"). Default provider defined by the configuration.
456
- verbose (bool, optional): Echo the API parameters in the response
457
- raw (bool, optional): Include raw data from this provider
466
+ ips: The IP(s) to be looked up
467
+ verbose: Echo the API parameters in the response
468
+ raw: Include raw data from this provider
469
+ provider: Use location data from this provider
458
470
 
459
471
  Raises:
460
472
  PangeaAPIException: If an API Error happens
@@ -464,15 +476,24 @@ class IpIntelAsync(ServiceBaseAsync):
464
476
  response.result field. Available response fields can be found in our [API documentation](/docs/api/ip-intel)
465
477
 
466
478
  Examples:
467
- FIXME:
479
+ response = await ip_intel.geolocate_bulk(
480
+ ips=["93.231.182.110"],
481
+ provider="digitalelement",
482
+ )
468
483
  """
469
- input = m.IPGeolocateBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
470
484
  return await self.request.post(
471
- "v2/geolocate", m.IPGeolocateBulkResult, data=input.model_dump(exclude_none=True)
485
+ "v2/geolocate",
486
+ m.IPGeolocateBulkResult,
487
+ data={"ips": ips, "verbose": verbose, "raw": raw, "provider": provider},
472
488
  )
473
489
 
474
490
  async def get_domain(
475
- self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
491
+ self,
492
+ ip: str,
493
+ *,
494
+ verbose: bool | None = None,
495
+ raw: bool | None = None,
496
+ provider: Literal["digitalenvoy", "digitalelement"] | None = None,
476
497
  ) -> PangeaResponse[m.IPDomainResult]:
477
498
  """
478
499
  Domain
@@ -482,10 +503,10 @@ class IpIntelAsync(ServiceBaseAsync):
482
503
  OperationId: ip_intel_post_v1_domain
483
504
 
484
505
  Args:
485
- ip (str): The IP to be looked up
486
- provider (str, optional): Use geolocation data from this provider ("digitalelement"). Default provider defined by the configuration.
487
- verbose (bool, optional): Echo the API parameters in the response
488
- raw (bool, optional): Include raw data from this provider
506
+ ip: The IP to be looked up
507
+ verbose: Echo the API parameters in the response
508
+ raw: Include raw data from this provider
509
+ provider: Use domain data from this provider
489
510
 
490
511
  Raises:
491
512
  PangeaAPIException: If an API Error happens
@@ -500,24 +521,30 @@ class IpIntelAsync(ServiceBaseAsync):
500
521
  provider="digitalelement",
501
522
  )
502
523
  """
503
- input = m.IPDomainRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
504
- return await self.request.post("v1/domain", m.IPDomainResult, data=input.model_dump(exclude_none=True))
524
+ return await self.request.post(
525
+ "v1/domain", m.IPDomainResult, data={"ip": ip, "verbose": verbose, "raw": raw, "provider": provider}
526
+ )
505
527
 
506
528
  async def get_domain_bulk(
507
- self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
529
+ self,
530
+ ips: SequenceNotStr[str],
531
+ *,
532
+ verbose: bool | None = None,
533
+ raw: bool | None = None,
534
+ provider: Literal["digitalenvoy", "digitalelement"] | None = None,
508
535
  ) -> PangeaResponse[m.IPDomainBulkResult]:
509
536
  """
510
537
  Domain
511
538
 
512
539
  Retrieve the domain name associated with an IP address.
513
540
 
514
- OperationId: FIXME:
541
+ OperationId: ip_intel_post_v2_domain
515
542
 
516
543
  Args:
517
- ips (List[str]): The IP to be looked up
518
- provider (str, optional): Use geolocation data from this provider ("digitalelement"). Default provider defined by the configuration.
519
- verbose (bool, optional): Echo the API parameters in the response
520
- raw (bool, optional): Include raw data from this provider
544
+ ips: The IP(s) to be looked up
545
+ verbose: Echo the API parameters in the response
546
+ raw: Include raw data from this provider
547
+ provider: Use domain data from this provider
521
548
 
522
549
  Raises:
523
550
  PangeaAPIException: If an API Error happens
@@ -527,13 +554,24 @@ class IpIntelAsync(ServiceBaseAsync):
527
554
  response.result field. Available response fields can be found in our [API documentation](/docs/api/ip-intel)
528
555
 
529
556
  Examples:
530
- FIXME:
557
+ response = await ip_intel.get_domain_bulk(
558
+ ips=["93.231.182.110"],
559
+ provider="digitalelement",
560
+ )
531
561
  """
532
- input = m.IPDomainBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
533
- return await self.request.post("v2/domain", m.IPDomainBulkResult, data=input.model_dump(exclude_none=True))
562
+ return await self.request.post(
563
+ "v2/domain",
564
+ m.IPDomainBulkResult,
565
+ data={"ips": ips, "verbose": verbose, "raw": raw, "provider": provider},
566
+ )
534
567
 
535
568
  async def is_vpn(
536
- self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
569
+ self,
570
+ ip: str,
571
+ *,
572
+ verbose: bool | None = None,
573
+ raw: bool | None = None,
574
+ provider: Literal["digitalenvoy", "digitalelement"] | None = None,
537
575
  ) -> PangeaResponse[m.IPVPNResult]:
538
576
  """
539
577
  VPN
@@ -543,10 +581,10 @@ class IpIntelAsync(ServiceBaseAsync):
543
581
  OperationId: ip_intel_post_v1_vpn
544
582
 
545
583
  Args:
546
- ip (str): The IP to be looked up
547
- provider (str, optional): Use geolocation data from this provider ("digitalelement"). Default provider defined by the configuration.
548
- verbose (bool, optional): Echo the API parameters in the response
549
- raw (bool, optional): Include raw data from this provider
584
+ ip: The IP to be looked up
585
+ verbose: Echo the API parameters in the response
586
+ raw: Include raw data from this provider
587
+ provider: Use vpn data from this provider
550
588
 
551
589
  Raises:
552
590
  PangeaAPIException: If an API Error happens
@@ -561,24 +599,32 @@ class IpIntelAsync(ServiceBaseAsync):
561
599
  provider="digitalelement",
562
600
  )
563
601
  """
564
- input = m.IPVPNRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
565
- return await self.request.post("v1/vpn", m.IPVPNResult, data=input.model_dump(exclude_none=True))
602
+ return await self.request.post(
603
+ "v1/vpn",
604
+ m.IPVPNResult,
605
+ data={"ip": ip, "verbose": verbose, "raw": raw, "provider": provider},
606
+ )
566
607
 
567
608
  async def is_vpn_bulk(
568
- self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
609
+ self,
610
+ ips: SequenceNotStr[str],
611
+ *,
612
+ verbose: bool | None = None,
613
+ raw: bool | None = None,
614
+ provider: Literal["digitalenvoy", "digitalelement"] | None = None,
569
615
  ) -> PangeaResponse[m.IPVPNBulkResult]:
570
616
  """
571
617
  VPN
572
618
 
573
619
  Determine if an IP address is provided by a VPN service.
574
620
 
575
- OperationId: FIXME:
621
+ OperationId: ip_intel_post_v2_vpn
576
622
 
577
623
  Args:
578
- ips (List[str]): The IP's list to be looked up
579
- provider (str, optional): Use geolocation data from this provider ("digitalelement"). Default provider defined by the configuration.
580
- verbose (bool, optional): Echo the API parameters in the response
581
- raw (bool, optional): Include raw data from this provider
624
+ ips: The IP(s) to be looked up
625
+ verbose: Echo the API parameters in the response
626
+ raw: Include raw data from this provider
627
+ provider: Use vpn data from this provider
582
628
 
583
629
  Raises:
584
630
  PangeaAPIException: If an API Error happens
@@ -588,13 +634,22 @@ class IpIntelAsync(ServiceBaseAsync):
588
634
  response.result field. Available response fields can be found in our [API documentation](/docs/api/ip-intel)
589
635
 
590
636
  Examples:
591
- FIXME:
637
+ response = await ip_intel.is_vpn_bulk(
638
+ ip="93.231.182.110",
639
+ provider="digitalelement",
640
+ )
592
641
  """
593
- input = m.IPVPNBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
594
- return await self.request.post("v2/vpn", m.IPVPNBulkResult, data=input.model_dump(exclude_none=True))
642
+ return await self.request.post(
643
+ "v2/vpn", m.IPVPNBulkResult, data={"ips": ips, "verbose": verbose, "raw": raw, "provider": provider}
644
+ )
595
645
 
596
646
  async def is_proxy(
597
- self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
647
+ self,
648
+ ip: str,
649
+ *,
650
+ verbose: bool | None = None,
651
+ raw: bool | None = None,
652
+ provider: Literal["digitalenvoy", "digitalelement"] | None = None,
598
653
  ) -> PangeaResponse[m.IPProxyResult]:
599
654
  """
600
655
  Proxy
@@ -604,10 +659,10 @@ class IpIntelAsync(ServiceBaseAsync):
604
659
  OperationId: ip_intel_post_v1_proxy
605
660
 
606
661
  Args:
607
- ip (str): The IP to be looked up
608
- provider (str, optional): Use geolocation data from this provider ("digitalelement"). Default provider defined by the configuration.
609
- verbose (bool, optional): Echo the API parameters in the response
610
- raw (bool, optional): Include raw data from this provider
662
+ ip: The IP to be looked up
663
+ verbose: Echo the API parameters in the response
664
+ raw: Include raw data from this provider
665
+ provider: Use proxy data from this provider
611
666
 
612
667
  Raises:
613
668
  PangeaAPIException: If an API Error happens
@@ -622,24 +677,30 @@ class IpIntelAsync(ServiceBaseAsync):
622
677
  provider="digitalelement",
623
678
  )
624
679
  """
625
- input = m.IPProxyRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
626
- return await self.request.post("v1/proxy", m.IPProxyResult, data=input.model_dump(exclude_none=True))
680
+ return await self.request.post(
681
+ "v1/proxy", m.IPProxyResult, data={"ip": ip, "verbose": verbose, "raw": raw, "provider": provider}
682
+ )
627
683
 
628
684
  async def is_proxy_bulk(
629
- self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
685
+ self,
686
+ ips: SequenceNotStr[str],
687
+ *,
688
+ verbose: bool | None = None,
689
+ raw: bool | None = None,
690
+ provider: Literal["digitalenvoy", "digitalelement"] | None = None,
630
691
  ) -> PangeaResponse[m.IPProxyBulkResult]:
631
692
  """
632
693
  Proxy
633
694
 
634
695
  Determine if an IP address is provided by a proxy service.
635
696
 
636
- OperationId: FIXME:
697
+ OperationId: ip_intel_post_v2_proxy
637
698
 
638
699
  Args:
639
- ips (List[str]): The IP's list to be looked up
640
- provider (str, optional): Use geolocation data from this provider ("digitalelement"). Default provider defined by the configuration.
641
- verbose (bool, optional): Echo the API parameters in the response
642
- raw (bool, optional): Include raw data from this provider
700
+ ips: The IP(s) to be looked up
701
+ verbose: Echo the API parameters in the response
702
+ raw: Include raw data from this provider
703
+ provider: Use proxy data from this provider
643
704
 
644
705
  Raises:
645
706
  PangeaAPIException: If an API Error happens
@@ -649,10 +710,14 @@ class IpIntelAsync(ServiceBaseAsync):
649
710
  response.result field. Available response fields can be found in our [API documentation](/docs/api/ip-intel)
650
711
 
651
712
  Examples:
652
- FIXME:
713
+ response = await ip_intel.is_proxy_bulk(
714
+ ips=["34.201.32.172"],
715
+ provider="digitalelement",
716
+ )
653
717
  """
654
- input = m.IPProxyBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
655
- return await self.request.post("v2/proxy", m.IPProxyBulkResult, data=input.model_dump(exclude_none=True))
718
+ return await self.request.post(
719
+ "v2/proxy", m.IPProxyBulkResult, data={"ips": ips, "verbose": verbose, "raw": raw, "provider": provider}
720
+ )
656
721
 
657
722
 
658
723
  class UrlIntelAsync(ServiceBaseAsync):