pangea-sdk 3.8.0b4__py3-none-any.whl → 4.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pangea/__init__.py +1 -2
- pangea/asyncio/request.py +17 -22
- pangea/asyncio/services/__init__.py +0 -2
- pangea/asyncio/services/audit.py +188 -23
- pangea/asyncio/services/authn.py +167 -108
- pangea/asyncio/services/authz.py +36 -45
- pangea/asyncio/services/embargo.py +2 -2
- pangea/asyncio/services/file_scan.py +3 -3
- pangea/asyncio/services/intel.py +44 -26
- pangea/asyncio/services/redact.py +60 -4
- pangea/asyncio/services/vault.py +145 -30
- pangea/dump_audit.py +1 -1
- pangea/request.py +30 -24
- pangea/response.py +34 -42
- pangea/services/__init__.py +0 -2
- pangea/services/audit/audit.py +202 -34
- pangea/services/audit/models.py +56 -8
- pangea/services/audit/util.py +3 -3
- pangea/services/authn/authn.py +116 -65
- pangea/services/authn/models.py +88 -4
- pangea/services/authz.py +51 -56
- pangea/services/base.py +23 -6
- pangea/services/embargo.py +2 -2
- pangea/services/file_scan.py +3 -2
- pangea/services/intel.py +25 -23
- pangea/services/redact.py +124 -4
- pangea/services/vault/models/common.py +121 -6
- pangea/services/vault/models/symmetric.py +2 -2
- pangea/services/vault/vault.py +143 -32
- pangea/utils.py +20 -109
- pangea/verify_audit.py +267 -83
- {pangea_sdk-3.8.0b4.dist-info → pangea_sdk-4.0.0.dist-info}/METADATA +12 -20
- pangea_sdk-4.0.0.dist-info/RECORD +46 -0
- {pangea_sdk-3.8.0b4.dist-info → pangea_sdk-4.0.0.dist-info}/WHEEL +1 -1
- pangea/asyncio/__init__.py +0 -1
- pangea/asyncio/file_uploader.py +0 -39
- pangea/asyncio/services/sanitize.py +0 -185
- pangea/asyncio/services/share.py +0 -573
- pangea/file_uploader.py +0 -35
- pangea/services/sanitize.py +0 -275
- pangea/services/share/file_format.py +0 -170
- pangea/services/share/share.py +0 -877
- pangea_sdk-3.8.0b4.dist-info/RECORD +0 -54
pangea/services/authz.py
CHANGED
@@ -20,10 +20,10 @@ class ItemOrder(str, enum.Enum):
|
|
20
20
|
|
21
21
|
|
22
22
|
class TupleOrderBy(str, enum.Enum):
|
23
|
-
|
23
|
+
RESOURCE_TYPE = "resource_type"
|
24
24
|
RESOURCE_ID = "resource_id"
|
25
25
|
RELATION = "relation"
|
26
|
-
|
26
|
+
SUBJECT_TYPE = "subject_type"
|
27
27
|
SUBJECT_ID = "subject_id"
|
28
28
|
SUBJECT_ACTION = "subject_action"
|
29
29
|
|
@@ -35,12 +35,12 @@ class TupleOrderBy(str, enum.Enum):
|
|
35
35
|
|
36
36
|
|
37
37
|
class Resource(PangeaResponseResult):
|
38
|
-
|
38
|
+
type: str
|
39
39
|
id: Optional[str] = None
|
40
40
|
|
41
41
|
|
42
42
|
class Subject(PangeaResponseResult):
|
43
|
-
|
43
|
+
type: str
|
44
44
|
id: Optional[str] = None
|
45
45
|
action: Optional[str] = None
|
46
46
|
|
@@ -60,18 +60,18 @@ class TupleCreateResult(PangeaResponseResult):
|
|
60
60
|
|
61
61
|
|
62
62
|
class TupleListFilter(APIRequestModel):
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
resource_type: Optional[str] = None
|
64
|
+
resource_type__contains: Optional[List[str]] = None
|
65
|
+
resource_type__in: Optional[List[str]] = None
|
66
66
|
resource_id: Optional[str] = None
|
67
67
|
resource_id__contains: Optional[List[str]] = None
|
68
68
|
resource_id__in: Optional[List[str]] = None
|
69
69
|
relation: Optional[str] = None
|
70
70
|
relation__contains: Optional[List[str]] = None
|
71
71
|
relation__in: Optional[List[str]] = None
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
subject_type: Optional[str] = None
|
73
|
+
subject_type__contains: Optional[List[str]] = None
|
74
|
+
subject_type__in: Optional[List[str]] = None
|
75
75
|
subject_id: Optional[str] = None
|
76
76
|
subject_id__contains: Optional[List[str]] = None
|
77
77
|
subject_id__in: Optional[List[str]] = None
|
@@ -111,9 +111,9 @@ class CheckRequest(APIRequestModel):
|
|
111
111
|
|
112
112
|
|
113
113
|
class DebugPath(APIResponseModel):
|
114
|
-
|
114
|
+
type: str
|
115
115
|
id: str
|
116
|
-
action: Optional[str]
|
116
|
+
action: Optional[str] = None
|
117
117
|
|
118
118
|
|
119
119
|
class Debug(APIResponseModel):
|
@@ -129,7 +129,7 @@ class CheckResult(PangeaResponseResult):
|
|
129
129
|
|
130
130
|
|
131
131
|
class ListResourcesRequest(APIRequestModel):
|
132
|
-
|
132
|
+
type: str
|
133
133
|
action: str
|
134
134
|
subject: Subject
|
135
135
|
|
@@ -148,12 +148,11 @@ class ListSubjectsResult(PangeaResponseResult):
|
|
148
148
|
|
149
149
|
|
150
150
|
class AuthZ(ServiceBase):
|
151
|
-
"""AuthZ service client.
|
151
|
+
"""AuthZ service client.
|
152
152
|
|
153
153
|
Provides methods to interact with the Pangea AuthZ Service.
|
154
154
|
Documentation for the AuthZ Service API can be found at
|
155
|
-
<https://pangea.cloud/docs/api/authz>.
|
156
|
-
is subject to change.
|
155
|
+
<https://pangea.cloud/docs/api/authz>.
|
157
156
|
|
158
157
|
Examples:
|
159
158
|
import os
|
@@ -174,11 +173,10 @@ class AuthZ(ServiceBase):
|
|
174
173
|
super().__init__(token, config, logger_name, config_id=config_id)
|
175
174
|
|
176
175
|
def tuple_create(self, tuples: List[Tuple]) -> PangeaResponse[TupleCreateResult]:
|
177
|
-
"""Create tuples.
|
176
|
+
"""Create tuples.
|
178
177
|
|
179
178
|
Create tuples in the AuthZ Service. The request will fail if there is no schema
|
180
179
|
or the tuples do not validate against the schema.
|
181
|
-
How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
|
182
180
|
|
183
181
|
Args:
|
184
182
|
tuples (List[Tuple]): List of tuples to be created.
|
@@ -189,22 +187,22 @@ class AuthZ(ServiceBase):
|
|
189
187
|
Returns:
|
190
188
|
Pangea Response with empty result.
|
191
189
|
Available response fields can be found in our
|
192
|
-
[API Documentation](https://pangea.cloud/docs/api/authz#/
|
190
|
+
[API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/create).
|
193
191
|
|
194
192
|
Examples:
|
195
193
|
response = authz.tuple_create(
|
196
194
|
tuples=[
|
197
195
|
Tuple(
|
198
|
-
resource=Resource(
|
196
|
+
resource=Resource(type="file", id="file_1"),
|
199
197
|
relation="owner",
|
200
|
-
subject=Subject(
|
198
|
+
subject=Subject(type="user", id="user_1"),
|
201
199
|
)
|
202
200
|
]
|
203
201
|
)
|
204
202
|
"""
|
205
203
|
|
206
204
|
input_data = TupleCreateRequest(tuples=tuples)
|
207
|
-
return self.request.post("
|
205
|
+
return self.request.post("v1/tuple/create", TupleCreateResult, data=input_data.model_dump(exclude_none=True))
|
208
206
|
|
209
207
|
def tuple_list(
|
210
208
|
self,
|
@@ -214,12 +212,11 @@ class AuthZ(ServiceBase):
|
|
214
212
|
order: Optional[ItemOrder] = None,
|
215
213
|
order_by: Optional[TupleOrderBy] = None,
|
216
214
|
) -> PangeaResponse[TupleListResult]:
|
217
|
-
"""List tuples.
|
215
|
+
"""List tuples.
|
218
216
|
|
219
217
|
Return a paginated list of filtered tuples. The filter is given in terms
|
220
218
|
of a tuple. Fill out the fields that you want to filter. If the filter
|
221
219
|
is empty it will return all the tuples.
|
222
|
-
How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
|
223
220
|
|
224
221
|
Args:
|
225
222
|
filter (TupleListFilter): The filter for listing tuples.
|
@@ -234,21 +231,20 @@ class AuthZ(ServiceBase):
|
|
234
231
|
Returns:
|
235
232
|
Pangea Response with a list of tuples and the last token.
|
236
233
|
Available response fields can be found in our
|
237
|
-
[API Documentation](https://pangea.cloud/docs/api/authz#/
|
234
|
+
[API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/list).
|
238
235
|
|
239
236
|
Examples:
|
240
|
-
authz.tuple_list(TupleListFilter(
|
237
|
+
authz.tuple_list(TupleListFilter(subject_type="user", subject_id="user_1"))
|
241
238
|
"""
|
242
239
|
input_data = TupleListRequest(
|
243
|
-
filter=filter.
|
240
|
+
filter=filter.model_dump(exclude_none=True), size=size, last=last, order=order, order_by=order_by
|
244
241
|
)
|
245
|
-
return self.request.post("
|
242
|
+
return self.request.post("v1/tuple/list", TupleListResult, data=input_data.model_dump(exclude_none=True))
|
246
243
|
|
247
244
|
def tuple_delete(self, tuples: List[Tuple]) -> PangeaResponse[TupleDeleteResult]:
|
248
|
-
"""Delete tuples.
|
245
|
+
"""Delete tuples.
|
249
246
|
|
250
247
|
Delete tuples in the AuthZ Service.
|
251
|
-
How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
|
252
248
|
|
253
249
|
Args:
|
254
250
|
tuples (List[Tuple]): List of tuples to be deleted.
|
@@ -259,22 +255,22 @@ class AuthZ(ServiceBase):
|
|
259
255
|
Returns:
|
260
256
|
Pangea Response with empty result.
|
261
257
|
Available response fields can be found in our
|
262
|
-
[API Documentation](https://pangea.cloud/docs/api/authz#/
|
258
|
+
[API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/delete).
|
263
259
|
|
264
260
|
Examples:
|
265
261
|
response = authz.tuple_delete(
|
266
262
|
tuples=[
|
267
263
|
Tuple(
|
268
|
-
resource=Resource(
|
264
|
+
resource=Resource(type="file", id="file_1"),
|
269
265
|
relation="owner",
|
270
|
-
subject=Subject(
|
266
|
+
subject=Subject(type="user", id="user_1"),
|
271
267
|
)
|
272
268
|
]
|
273
269
|
)
|
274
270
|
"""
|
275
271
|
|
276
272
|
input_data = TupleDeleteRequest(tuples=tuples)
|
277
|
-
return self.request.post("
|
273
|
+
return self.request.post("v1/tuple/delete", TupleDeleteResult, data=input_data.model_dump(exclude_none=True))
|
278
274
|
|
279
275
|
def check(
|
280
276
|
self,
|
@@ -284,10 +280,9 @@ class AuthZ(ServiceBase):
|
|
284
280
|
debug: Optional[bool] = None,
|
285
281
|
attributes: Optional[Dict[str, Union[int, str]]] = None,
|
286
282
|
) -> PangeaResponse[CheckResult]:
|
287
|
-
"""Perform a check request.
|
283
|
+
"""Perform a check request.
|
288
284
|
|
289
285
|
Check if a subject has permission to perform an action on the resource.
|
290
|
-
How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
|
291
286
|
|
292
287
|
Args:
|
293
288
|
resource (Resource): The resource to check.
|
@@ -302,29 +297,28 @@ class AuthZ(ServiceBase):
|
|
302
297
|
Returns:
|
303
298
|
Pangea Response with the result of the check.
|
304
299
|
Available response fields can be found in our
|
305
|
-
[API Documentation](https://pangea.cloud/docs/api/authz#/
|
300
|
+
[API Documentation](https://pangea.cloud/docs/api/authz#/v1/check).
|
306
301
|
|
307
302
|
Examples:
|
308
303
|
response = authz.check(
|
309
|
-
resource=Resource(
|
304
|
+
resource=Resource(type="file", id="file_1"),
|
310
305
|
action="update",
|
311
|
-
subject=Subject(
|
306
|
+
subject=Subject(type="user", id="user_1"),
|
312
307
|
debug=True,
|
313
308
|
)
|
314
309
|
"""
|
315
310
|
|
316
311
|
input_data = CheckRequest(resource=resource, action=action, subject=subject, debug=debug, attributes=attributes)
|
317
|
-
return self.request.post("
|
312
|
+
return self.request.post("v1/check", CheckResult, data=input_data.model_dump(exclude_none=True))
|
318
313
|
|
319
|
-
def list_resources(self,
|
320
|
-
"""List resources.
|
314
|
+
def list_resources(self, type: str, action: str, subject: Subject) -> PangeaResponse[ListResourcesResult]:
|
315
|
+
"""List resources.
|
321
316
|
|
322
|
-
Given a
|
323
|
-
|
324
|
-
How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
|
317
|
+
Given a type, action, and subject, list all the resources in the
|
318
|
+
type that the subject has access to the action with.
|
325
319
|
|
326
320
|
Args:
|
327
|
-
|
321
|
+
type (str): The type to filter resources.
|
328
322
|
action (str): The action to filter resources.
|
329
323
|
subject (Subject): The subject to filter resources.
|
330
324
|
|
@@ -334,25 +328,26 @@ class AuthZ(ServiceBase):
|
|
334
328
|
Returns:
|
335
329
|
Pangea Response with a list of resource IDs.
|
336
330
|
Available response fields can be found in our
|
337
|
-
[API Documentation](https://pangea.cloud/docs/api/authz#/
|
331
|
+
[API Documentation](https://pangea.cloud/docs/api/authz#/v1/list-resources).
|
338
332
|
|
339
333
|
Examples:
|
340
334
|
authz.list_resources(
|
341
|
-
|
335
|
+
type="file",
|
342
336
|
action="update",
|
343
|
-
subject=Subject(
|
337
|
+
subject=Subject(type="user", id="user_1"),
|
344
338
|
)
|
345
339
|
"""
|
346
340
|
|
347
|
-
input_data = ListResourcesRequest(
|
348
|
-
return self.request.post(
|
341
|
+
input_data = ListResourcesRequest(type=type, action=action, subject=subject)
|
342
|
+
return self.request.post(
|
343
|
+
"v1/list-resources", ListResourcesResult, data=input_data.model_dump(exclude_none=True)
|
344
|
+
)
|
349
345
|
|
350
346
|
def list_subjects(self, resource: Resource, action: str) -> PangeaResponse[ListSubjectsResult]:
|
351
|
-
"""List subjects.
|
347
|
+
"""List subjects.
|
352
348
|
|
353
349
|
Given a resource and an action, return the list of subjects who have
|
354
350
|
access to the action for the given resource.
|
355
|
-
How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
|
356
351
|
|
357
352
|
Args:
|
358
353
|
resource (Resource): The resource to filter subjects.
|
@@ -364,14 +359,14 @@ class AuthZ(ServiceBase):
|
|
364
359
|
Returns:
|
365
360
|
Pangea Response with a list of subjects.
|
366
361
|
Available response fields can be found in our
|
367
|
-
[API Documentation](https://pangea.cloud/docs/api/authz#/
|
362
|
+
[API Documentation](https://pangea.cloud/docs/api/authz#/v1/list-subjects).
|
368
363
|
|
369
364
|
Examples:
|
370
365
|
response = authz.list_subjects(
|
371
|
-
resource=Resource(
|
366
|
+
resource=Resource(type="file", id="file_1"),
|
372
367
|
action="update",
|
373
368
|
)
|
374
369
|
"""
|
375
370
|
|
376
371
|
input_data = ListSubjectsRequest(resource=resource, action=action)
|
377
|
-
return self.request.post("
|
372
|
+
return self.request.post("v1/list-subjects", ListSubjectsResult, data=input_data.model_dump(exclude_none=True))
|
pangea/services/base.py
CHANGED
@@ -1,23 +1,40 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
from __future__ import annotations
|
3
4
|
|
4
5
|
import copy
|
5
6
|
import logging
|
6
7
|
from typing import Dict, Optional, Type, Union
|
7
8
|
|
9
|
+
from typing_extensions import TypeVar
|
10
|
+
|
8
11
|
from pangea.asyncio.request import PangeaRequestAsync
|
9
12
|
from pangea.config import PangeaConfig
|
10
13
|
from pangea.exceptions import AcceptedRequestException
|
11
14
|
from pangea.request import PangeaRequest
|
12
15
|
from pangea.response import AttachedFile, PangeaResponse, PangeaResponseResult
|
13
16
|
|
17
|
+
TResult = TypeVar("TResult", bound=PangeaResponseResult, default=PangeaResponseResult)
|
18
|
+
|
14
19
|
|
15
20
|
class ServiceBase(object):
|
16
21
|
service_name: str = "base"
|
17
22
|
|
18
23
|
def __init__(
|
19
|
-
self,
|
20
|
-
|
24
|
+
self,
|
25
|
+
token: str,
|
26
|
+
config: PangeaConfig | None = None,
|
27
|
+
logger_name: str = "pangea",
|
28
|
+
config_id: str | None = None,
|
29
|
+
) -> None:
|
30
|
+
"""
|
31
|
+
Initializes a new Pangea service client.
|
32
|
+
|
33
|
+
Args:
|
34
|
+
token: Pangea API token.
|
35
|
+
config: Configuration.
|
36
|
+
logger_name: Logger name.
|
37
|
+
"""
|
21
38
|
if not token:
|
22
39
|
raise Exception("No token provided")
|
23
40
|
|
@@ -30,11 +47,11 @@ class ServiceBase(object):
|
|
30
47
|
self.request.set_extra_headers(extra_headers)
|
31
48
|
|
32
49
|
@property
|
33
|
-
def token(self):
|
50
|
+
def token(self) -> str:
|
34
51
|
return self._token
|
35
52
|
|
36
53
|
@token.setter
|
37
|
-
def token(self, value):
|
54
|
+
def token(self, value: str) -> None:
|
38
55
|
self._token = value
|
39
56
|
|
40
57
|
@property
|
@@ -55,8 +72,8 @@ class ServiceBase(object):
|
|
55
72
|
exception: Optional[AcceptedRequestException] = None,
|
56
73
|
response: Optional[PangeaResponse] = None,
|
57
74
|
request_id: Optional[str] = None,
|
58
|
-
result_class:
|
59
|
-
) -> PangeaResponse:
|
75
|
+
result_class: Type[TResult] = PangeaResponseResult, # type: ignore[assignment]
|
76
|
+
) -> PangeaResponse[TResult]:
|
60
77
|
"""
|
61
78
|
Poll result
|
62
79
|
|
pangea/services/embargo.py
CHANGED
@@ -103,7 +103,7 @@ class Embargo(ServiceBase):
|
|
103
103
|
response = embargo.ip_check("190.6.64.94")
|
104
104
|
"""
|
105
105
|
input = IPCheckRequest(ip=ip)
|
106
|
-
return self.request.post("v1/ip/check", EmbargoResult, data=input.
|
106
|
+
return self.request.post("v1/ip/check", EmbargoResult, data=input.model_dump())
|
107
107
|
|
108
108
|
def iso_check(self, iso_code: str) -> PangeaResponse[EmbargoResult]:
|
109
109
|
"""
|
@@ -130,4 +130,4 @@ class Embargo(ServiceBase):
|
|
130
130
|
response = embargo.iso_check("CU")
|
131
131
|
"""
|
132
132
|
input = ISOCheckRequest(iso_code=iso_code)
|
133
|
-
return self.request.post("v1/iso/check", result_class=EmbargoResult, data=input.
|
133
|
+
return self.request.post("v1/iso/check", result_class=EmbargoResult, data=input.model_dump())
|
pangea/services/file_scan.py
CHANGED
@@ -71,6 +71,7 @@ class FileScan(ServiceBase):
|
|
71
71
|
"""
|
72
72
|
|
73
73
|
service_name = "file-scan"
|
74
|
+
version = "v1"
|
74
75
|
|
75
76
|
def file_scan(
|
76
77
|
self,
|
@@ -141,7 +142,7 @@ class FileScan(ServiceBase):
|
|
141
142
|
transfer_method=transfer_method,
|
142
143
|
source_url=source_url,
|
143
144
|
)
|
144
|
-
data = input.
|
145
|
+
data = input.model_dump(exclude_none=True)
|
145
146
|
return self.request.post("v1/scan", FileScanResult, data=data, files=files, poll_result=sync_call)
|
146
147
|
|
147
148
|
def request_upload_url(
|
@@ -163,7 +164,7 @@ class FileScan(ServiceBase):
|
|
163
164
|
input.sha256 = params.sha256_hex
|
164
165
|
input.size = params.size
|
165
166
|
|
166
|
-
data = input.
|
167
|
+
data = input.model_dump(exclude_none=True)
|
167
168
|
return self.request.request_presigned_url("v1/scan", FileScanResult, data=data)
|
168
169
|
|
169
170
|
|
pangea/services/intel.py
CHANGED
@@ -524,7 +524,7 @@ class FileIntel(ServiceBase):
|
|
524
524
|
)
|
525
525
|
"""
|
526
526
|
input = FileReputationRequest(hash=hash, hash_type=hash_type, verbose=verbose, raw=raw, provider=provider)
|
527
|
-
return self.request.post("v1/reputation", FileReputationResult, data=input.
|
527
|
+
return self.request.post("v1/reputation", FileReputationResult, data=input.model_dump(exclude_none=True))
|
528
528
|
|
529
529
|
def hash_reputation_bulk(
|
530
530
|
self,
|
@@ -563,7 +563,7 @@ class FileIntel(ServiceBase):
|
|
563
563
|
input = FileReputationBulkRequest( # type: ignore[call-arg]
|
564
564
|
hashes=hashes, hash_type=hash_type, verbose=verbose, raw=raw, provider=provider
|
565
565
|
)
|
566
|
-
return self.request.post("v2/reputation", FileReputationBulkResult, data=input.
|
566
|
+
return self.request.post("v2/reputation", FileReputationBulkResult, data=input.model_dump(exclude_none=True))
|
567
567
|
|
568
568
|
def filepath_reputation(
|
569
569
|
self,
|
@@ -708,7 +708,7 @@ class DomainIntel(ServiceBase):
|
|
708
708
|
)
|
709
709
|
"""
|
710
710
|
input = DomainReputationRequest(domain=domain, verbose=verbose, provider=provider, raw=raw)
|
711
|
-
return self.request.post("v1/reputation", DomainReputationResult, data=input.
|
711
|
+
return self.request.post("v1/reputation", DomainReputationResult, data=input.model_dump(exclude_none=True))
|
712
712
|
|
713
713
|
def reputation_bulk(
|
714
714
|
self,
|
@@ -744,7 +744,7 @@ class DomainIntel(ServiceBase):
|
|
744
744
|
)
|
745
745
|
"""
|
746
746
|
input = DomainReputationBulkRequest(domains=domains, verbose=verbose, provider=provider, raw=raw)
|
747
|
-
return self.request.post("v2/reputation", DomainReputationBulkResult, data=input.
|
747
|
+
return self.request.post("v2/reputation", DomainReputationBulkResult, data=input.model_dump(exclude_none=True))
|
748
748
|
|
749
749
|
def who_is(
|
750
750
|
self, domain: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -776,7 +776,7 @@ class DomainIntel(ServiceBase):
|
|
776
776
|
)
|
777
777
|
"""
|
778
778
|
input = DomainWhoIsRequest(domain=domain, verbose=verbose, provider=provider, raw=raw) # type: ignore[call-arg]
|
779
|
-
return self.request.post("v1/whois", DomainWhoIsResult, data=input.
|
779
|
+
return self.request.post("v1/whois", DomainWhoIsResult, data=input.model_dump(exclude_none=True))
|
780
780
|
|
781
781
|
|
782
782
|
class IpIntel(ServiceBase):
|
@@ -835,11 +835,11 @@ class IpIntel(ServiceBase):
|
|
835
835
|
)
|
836
836
|
"""
|
837
837
|
input = IPReputationRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
838
|
-
return self.request.post("v1/reputation", IPReputationResult, data=input.
|
838
|
+
return self.request.post("v1/reputation", IPReputationResult, data=input.model_dump(exclude_none=True))
|
839
839
|
|
840
840
|
def reputation_bulk(
|
841
841
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
842
|
-
) -> PangeaResponse[
|
842
|
+
) -> PangeaResponse[IPReputationBulkResult]:
|
843
843
|
"""
|
844
844
|
Reputation V2
|
845
845
|
|
@@ -867,7 +867,7 @@ class IpIntel(ServiceBase):
|
|
867
867
|
)
|
868
868
|
"""
|
869
869
|
input = IPReputationBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
870
|
-
return self.request.post("v2/reputation", IPReputationBulkResult, data=input.
|
870
|
+
return self.request.post("v2/reputation", IPReputationBulkResult, data=input.model_dump(exclude_none=True))
|
871
871
|
|
872
872
|
def geolocate(
|
873
873
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -899,7 +899,7 @@ class IpIntel(ServiceBase):
|
|
899
899
|
)
|
900
900
|
"""
|
901
901
|
input = IPGeolocateRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
902
|
-
return self.request.post("v1/geolocate", IPGeolocateResult, data=input.
|
902
|
+
return self.request.post("v1/geolocate", IPGeolocateResult, data=input.model_dump(exclude_none=True))
|
903
903
|
|
904
904
|
def geolocate_bulk(
|
905
905
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -931,7 +931,7 @@ class IpIntel(ServiceBase):
|
|
931
931
|
)
|
932
932
|
"""
|
933
933
|
input = IPGeolocateBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
934
|
-
return self.request.post("v2/geolocate", IPGeolocateBulkResult, data=input.
|
934
|
+
return self.request.post("v2/geolocate", IPGeolocateBulkResult, data=input.model_dump(exclude_none=True))
|
935
935
|
|
936
936
|
def get_domain(
|
937
937
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -963,7 +963,7 @@ class IpIntel(ServiceBase):
|
|
963
963
|
)
|
964
964
|
"""
|
965
965
|
input = IPDomainRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
966
|
-
return self.request.post("v1/domain", IPDomainResult, data=input.
|
966
|
+
return self.request.post("v1/domain", IPDomainResult, data=input.model_dump(exclude_none=True))
|
967
967
|
|
968
968
|
def get_domain_bulk(
|
969
969
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -995,7 +995,7 @@ class IpIntel(ServiceBase):
|
|
995
995
|
)
|
996
996
|
"""
|
997
997
|
input = IPDomainBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
998
|
-
return self.request.post("v2/domain", IPDomainBulkResult, data=input.
|
998
|
+
return self.request.post("v2/domain", IPDomainBulkResult, data=input.model_dump(exclude_none=True))
|
999
999
|
|
1000
1000
|
def is_vpn(
|
1001
1001
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -1027,7 +1027,7 @@ class IpIntel(ServiceBase):
|
|
1027
1027
|
)
|
1028
1028
|
"""
|
1029
1029
|
input = IPVPNRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
1030
|
-
return self.request.post("v1/vpn", IPVPNResult, data=input.
|
1030
|
+
return self.request.post("v1/vpn", IPVPNResult, data=input.model_dump(exclude_none=True))
|
1031
1031
|
|
1032
1032
|
def is_vpn_bulk(
|
1033
1033
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -1059,7 +1059,7 @@ class IpIntel(ServiceBase):
|
|
1059
1059
|
)
|
1060
1060
|
"""
|
1061
1061
|
input = IPVPNBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
1062
|
-
return self.request.post("v2/vpn", IPVPNBulkResult, data=input.
|
1062
|
+
return self.request.post("v2/vpn", IPVPNBulkResult, data=input.model_dump(exclude_none=True))
|
1063
1063
|
|
1064
1064
|
def is_proxy(
|
1065
1065
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -1091,7 +1091,7 @@ class IpIntel(ServiceBase):
|
|
1091
1091
|
)
|
1092
1092
|
"""
|
1093
1093
|
input = IPProxyRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
1094
|
-
return self.request.post("v1/proxy", IPProxyResult, data=input.
|
1094
|
+
return self.request.post("v1/proxy", IPProxyResult, data=input.model_dump(exclude_none=True))
|
1095
1095
|
|
1096
1096
|
def is_proxy_bulk(
|
1097
1097
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -1123,7 +1123,7 @@ class IpIntel(ServiceBase):
|
|
1123
1123
|
)
|
1124
1124
|
"""
|
1125
1125
|
input = IPProxyBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
1126
|
-
return self.request.post("v2/proxy", IPProxyBulkResult, data=input.
|
1126
|
+
return self.request.post("v2/proxy", IPProxyBulkResult, data=input.model_dump(exclude_none=True))
|
1127
1127
|
|
1128
1128
|
|
1129
1129
|
class UrlIntel(ServiceBase):
|
@@ -1187,7 +1187,7 @@ class UrlIntel(ServiceBase):
|
|
1187
1187
|
"""
|
1188
1188
|
|
1189
1189
|
input = URLReputationRequest(url=url, provider=provider, verbose=verbose, raw=raw)
|
1190
|
-
return self.request.post("v1/reputation", URLReputationResult, data=input.
|
1190
|
+
return self.request.post("v1/reputation", URLReputationResult, data=input.model_dump(exclude_none=True))
|
1191
1191
|
|
1192
1192
|
def reputation_bulk(
|
1193
1193
|
self,
|
@@ -1195,7 +1195,7 @@ class UrlIntel(ServiceBase):
|
|
1195
1195
|
verbose: Optional[bool] = None,
|
1196
1196
|
raw: Optional[bool] = None,
|
1197
1197
|
provider: Optional[str] = None,
|
1198
|
-
) -> PangeaResponse[
|
1198
|
+
) -> PangeaResponse[URLReputationBulkResult]:
|
1199
1199
|
"""
|
1200
1200
|
Reputation V2
|
1201
1201
|
|
@@ -1224,7 +1224,7 @@ class UrlIntel(ServiceBase):
|
|
1224
1224
|
"""
|
1225
1225
|
|
1226
1226
|
input = URLReputationBulkRequest(urls=urls, provider=provider, verbose=verbose, raw=raw)
|
1227
|
-
return self.request.post("v2/reputation", URLReputationBulkResult, data=input.
|
1227
|
+
return self.request.post("v2/reputation", URLReputationBulkResult, data=input.model_dump(exclude_none=True))
|
1228
1228
|
|
1229
1229
|
|
1230
1230
|
class UserBreachedRequest(IntelCommonRequest):
|
@@ -1431,7 +1431,7 @@ class UserIntel(ServiceBase):
|
|
1431
1431
|
verbose=verbose,
|
1432
1432
|
raw=raw,
|
1433
1433
|
)
|
1434
|
-
return self.request.post("v1/user/breached", UserBreachedResult, data=input.
|
1434
|
+
return self.request.post("v1/user/breached", UserBreachedResult, data=input.model_dump(exclude_none=True))
|
1435
1435
|
|
1436
1436
|
def user_breached_bulk(
|
1437
1437
|
self,
|
@@ -1490,7 +1490,7 @@ class UserIntel(ServiceBase):
|
|
1490
1490
|
verbose=verbose,
|
1491
1491
|
raw=raw,
|
1492
1492
|
)
|
1493
|
-
return self.request.post("v2/user/breached", UserBreachedBulkResult, data=input.
|
1493
|
+
return self.request.post("v2/user/breached", UserBreachedBulkResult, data=input.model_dump(exclude_none=True))
|
1494
1494
|
|
1495
1495
|
def password_breached(
|
1496
1496
|
self,
|
@@ -1532,7 +1532,9 @@ class UserIntel(ServiceBase):
|
|
1532
1532
|
input = UserPasswordBreachedRequest(
|
1533
1533
|
hash_type=hash_type, hash_prefix=hash_prefix, provider=provider, verbose=verbose, raw=raw
|
1534
1534
|
)
|
1535
|
-
return self.request.post(
|
1535
|
+
return self.request.post(
|
1536
|
+
"v1/password/breached", UserPasswordBreachedResult, data=input.model_dump(exclude_none=True)
|
1537
|
+
)
|
1536
1538
|
|
1537
1539
|
def password_breached_bulk(
|
1538
1540
|
self,
|
@@ -1575,7 +1577,7 @@ class UserIntel(ServiceBase):
|
|
1575
1577
|
hash_type=hash_type, hash_prefixes=hash_prefixes, provider=provider, verbose=verbose, raw=raw
|
1576
1578
|
)
|
1577
1579
|
return self.request.post(
|
1578
|
-
"v2/password/breached", UserPasswordBreachedBulkResult, data=input.
|
1580
|
+
"v2/password/breached", UserPasswordBreachedBulkResult, data=input.model_dump(exclude_none=True)
|
1579
1581
|
)
|
1580
1582
|
|
1581
1583
|
class PasswordStatus(enum.Enum):
|