pangea-sdk 3.8.0__py3-none-any.whl → 3.8.0b2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pangea/__init__.py CHANGED
@@ -1,6 +1,7 @@
1
- __version__ = "3.8.0"
1
+ __version__ = "3.8.0beta2"
2
2
 
3
3
  from pangea.asyncio.request import PangeaRequestAsync
4
4
  from pangea.config import PangeaConfig
5
+ from pangea.file_uploader import FileUploader
5
6
  from pangea.request import PangeaRequest
6
7
  from pangea.response import PangeaResponse
@@ -0,0 +1 @@
1
+ from .file_uploader import FileUploaderAsync
@@ -0,0 +1,39 @@
1
+ # Copyright 2022 Pangea Cyber Corporation
2
+ # Author: Pangea Cyber Corporation
3
+ import io
4
+ import logging
5
+ from typing import Dict, Optional
6
+
7
+ from pangea.asyncio.request import PangeaRequestAsync
8
+ from pangea.request import PangeaConfig
9
+ from pangea.response import TransferMethod
10
+
11
+
12
+ class FileUploaderAsync:
13
+ def __init__(self) -> None:
14
+ self.logger = logging.getLogger("pangea")
15
+ self._request: PangeaRequestAsync = PangeaRequestAsync(
16
+ config=PangeaConfig(),
17
+ token="",
18
+ service="FileUploader",
19
+ logger=self.logger,
20
+ )
21
+
22
+ async def upload_file(
23
+ self,
24
+ url: str,
25
+ file: io.BufferedReader,
26
+ transfer_method: TransferMethod = TransferMethod.PUT_URL,
27
+ file_details: Optional[Dict] = None,
28
+ ) -> None:
29
+ if transfer_method == TransferMethod.PUT_URL:
30
+ files = [("file", ("filename", file, "application/octet-stream"))]
31
+ await self._request.put_presigned_url(url=url, files=files) # type: ignore[arg-type]
32
+ elif transfer_method == TransferMethod.POST_URL:
33
+ files = [("file", ("filename", file, "application/octet-stream"))]
34
+ await self._request.post_presigned_url(url=url, data=file_details, files=files) # type: ignore[arg-type]
35
+ else:
36
+ raise ValueError(f"Transfer method not supported: {transfer_method}")
37
+
38
+ async def close(self) -> None:
39
+ await self._request.session.close()
pangea/asyncio/request.py CHANGED
@@ -3,20 +3,18 @@
3
3
 
4
4
  import asyncio
5
5
  import json
6
+ import os
6
7
  import time
7
8
  from typing import Dict, List, Optional, Tuple, Type, Union
8
9
 
9
10
  import aiohttp
10
11
  from aiohttp import FormData
11
- from typing_extensions import TypeVar
12
12
 
13
13
  import pangea.exceptions as pe
14
14
  from pangea.request import MultipartResponse, PangeaRequestBase
15
15
  from pangea.response import AttachedFile, PangeaResponse, PangeaResponseResult, ResponseStatus, TransferMethod
16
16
  from pangea.utils import default_encoder
17
17
 
18
- TResult = TypeVar("TResult", bound=PangeaResponseResult, default=PangeaResponseResult)
19
-
20
18
 
21
19
  class PangeaRequestAsync(PangeaRequestBase):
22
20
  """An object that makes direct calls to Pangea Service APIs.
@@ -30,12 +28,12 @@ class PangeaRequestAsync(PangeaRequestBase):
30
28
  async def post(
31
29
  self,
32
30
  endpoint: str,
33
- result_class: Type[TResult],
31
+ result_class: Type[PangeaResponseResult],
34
32
  data: Union[str, Dict] = {},
35
33
  files: List[Tuple] = [],
36
34
  poll_result: bool = True,
37
35
  url: Optional[str] = None,
38
- ) -> PangeaResponse[TResult]:
36
+ ) -> PangeaResponse:
39
37
  """Makes the POST call to a Pangea Service endpoint.
40
38
 
41
39
  Args:
@@ -93,7 +91,9 @@ class PangeaRequestAsync(PangeaRequestBase):
93
91
 
94
92
  return self._check_response(pangea_response)
95
93
 
96
- async def get(self, path: str, result_class: Type[TResult], check_response: bool = True) -> PangeaResponse[TResult]:
94
+ async def get(
95
+ self, path: str, result_class: Type[PangeaResponseResult], check_response: bool = True
96
+ ) -> PangeaResponse[Type[PangeaResponseResult]]:
97
97
  """Makes the GET call to a Pangea Service endpoint.
98
98
 
99
99
  Args:
@@ -110,7 +110,7 @@ class PangeaRequestAsync(PangeaRequestBase):
110
110
 
111
111
  async with self.session.get(url, headers=self._headers()) as requests_response:
112
112
  await self._check_http_errors(requests_response)
113
- pangea_response = PangeaResponse(
113
+ pangea_response = PangeaResponse( # type: ignore[var-annotated]
114
114
  requests_response, result_class=result_class, json=await requests_response.json()
115
115
  )
116
116
 
@@ -131,11 +131,11 @@ class PangeaRequestAsync(PangeaRequestBase):
131
131
  raise pe.ServiceTemporarilyUnavailable(await resp.json())
132
132
 
133
133
  async def poll_result_by_id(
134
- self, request_id: str, result_class: Type[TResult], check_response: bool = True
135
- ) -> PangeaResponse[TResult]:
134
+ self, request_id: str, result_class: Union[Type[PangeaResponseResult], Type[dict]], check_response: bool = True
135
+ ):
136
136
  path = self._get_poll_path(request_id)
137
137
  self.logger.debug(json.dumps({"service": self.service, "action": "poll_result_once", "url": path}))
138
- return await self.get(path, result_class, check_response=check_response)
138
+ return await self.get(path, result_class, check_response=check_response) # type: ignore[arg-type]
139
139
 
140
140
  async def poll_result_once(self, response: PangeaResponse, check_response: bool = True):
141
141
  request_id = response.request_id
@@ -180,6 +180,7 @@ class PangeaRequestAsync(PangeaRequestBase):
180
180
  "service": self.service,
181
181
  "action": "download_file",
182
182
  "url": url,
183
+ "filename": filename,
183
184
  "status": "start",
184
185
  }
185
186
  )
@@ -295,6 +296,9 @@ class PangeaRequestAsync(PangeaRequestBase):
295
296
  raise AttributeError("files attribute should have at least 1 file")
296
297
 
297
298
  response = await self.request_presigned_url(endpoint=endpoint, result_class=result_class, data=data)
299
+ if response.success: # This should only happen when uploading a zero bytes file
300
+ return response.raw_response
301
+
298
302
  if response.accepted_result is None:
299
303
  raise pe.PangeaException("No accepted_result field when requesting presigned url")
300
304
  if response.accepted_result.post_url is None:
@@ -314,9 +318,8 @@ class PangeaRequestAsync(PangeaRequestBase):
314
318
  ) -> PangeaResponse:
315
319
  # Send request
316
320
  try:
317
- # This should return 202 (AcceptedRequestException)
318
- resp = await self.post(endpoint=endpoint, result_class=result_class, data=data, poll_result=False)
319
- raise pe.PresignedURLException("Should return 202", resp)
321
+ # This should return 202 (AcceptedRequestException) at least zero size file is sent
322
+ return await self.post(endpoint=endpoint, result_class=result_class, data=data, poll_result=False)
320
323
  except pe.AcceptedRequestException as e:
321
324
  accepted_exception = e
322
325
  except Exception as e:
@@ -325,7 +328,9 @@ class PangeaRequestAsync(PangeaRequestBase):
325
328
  # Receive 202
326
329
  return await self._poll_presigned_url(accepted_exception.response)
327
330
 
328
- async def _poll_presigned_url(self, response: PangeaResponse[TResult]) -> PangeaResponse[TResult]:
331
+ async def _poll_presigned_url(
332
+ self, response: PangeaResponse[Type[PangeaResponseResult]]
333
+ ) -> PangeaResponse[Type[PangeaResponseResult]]:
329
334
  if response.http_status != 202:
330
335
  raise AttributeError("Response should be 202")
331
336
 
@@ -1,8 +1,9 @@
1
1
  from .audit import AuditAsync
2
2
  from .authn import AuthNAsync
3
- from .authz import AuthZAsync
4
3
  from .embargo import EmbargoAsync
5
4
  from .file_scan import FileScanAsync
6
5
  from .intel import DomainIntelAsync, FileIntelAsync, IpIntelAsync, UrlIntelAsync, UserIntelAsync
7
6
  from .redact import RedactAsync
7
+ from .share import ShareAsync
8
+ from .sanitize import SanitizeAsync
8
9
  from .vault import VaultAsync
@@ -1,14 +1,11 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
- from __future__ import annotations
4
-
5
3
  import datetime
6
- from typing import Any, Dict, List, Optional, Sequence, Union
4
+ from typing import Any, Dict, List, Optional, Union
7
5
 
8
6
  import pangea.exceptions as pexc
9
7
  from pangea.asyncio.services.base import ServiceBaseAsync
10
- from pangea.config import PangeaConfig
11
- from pangea.response import PangeaResponse, PangeaResponseResult
8
+ from pangea.response import PangeaResponse
12
9
  from pangea.services.audit.audit import AuditBase
13
10
  from pangea.services.audit.exceptions import AuditException
14
11
  from pangea.services.audit.models import (
@@ -16,7 +13,6 @@ from pangea.services.audit.models import (
16
13
  DownloadRequest,
17
14
  DownloadResult,
18
15
  Event,
19
- ExportRequest,
20
16
  LogBulkResult,
21
17
  LogResult,
22
18
  PublishedRoot,
@@ -60,33 +56,14 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
60
56
 
61
57
  def __init__(
62
58
  self,
63
- token: str,
64
- config: PangeaConfig | None = None,
59
+ token,
60
+ config=None,
65
61
  private_key_file: str = "",
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
-
62
+ public_key_info: Dict[str, str] = {},
63
+ tenant_id: Optional[str] = None,
64
+ logger_name="pangea",
65
+ config_id: Optional[str] = None,
66
+ ):
90
67
  # FIXME: Temporary check to deprecate config_id from PangeaConfig.
91
68
  # Delete it when deprecate PangeaConfig.config_id
92
69
  if config_id and config is not None and config.config_id is not None:
@@ -295,7 +272,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
295
272
  end: Optional[Union[datetime.datetime, str]] = None,
296
273
  limit: Optional[int] = None,
297
274
  max_results: Optional[int] = None,
298
- search_restriction: Optional[Dict[str, Sequence[str]]] = None,
275
+ search_restriction: Optional[dict] = None,
299
276
  verbose: Optional[bool] = None,
300
277
  verify_consistency: bool = False,
301
278
  verify_events: bool = True,
@@ -324,7 +301,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
324
301
  end (datetime, optional): An RFC-3339 formatted timestamp, or relative time adjustment from the current time.
325
302
  limit (int, optional): Optional[int] = None,
326
303
  max_results (int, optional): Maximum number of results to return.
327
- search_restriction (Dict[str, Sequence[str]], optional): A list of keys to restrict the search results to. Useful for partitioning data available to the query string.
304
+ search_restriction (dict, optional): A list of keys to restrict the search results to. Useful for partitioning data available to the query string.
328
305
  verbose (bool, optional): If true, response include root and membership and consistency proofs.
329
306
  verify_consistency (bool): True to verify logs consistency
330
307
  verify_events (bool): True to verify hash events and signatures
@@ -370,7 +347,6 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
370
347
  id: str,
371
348
  limit: Optional[int] = 20,
372
349
  offset: Optional[int] = 0,
373
- assert_search_restriction: Optional[Dict[str, Sequence[str]]] = None,
374
350
  verify_consistency: bool = False,
375
351
  verify_events: bool = True,
376
352
  ) -> PangeaResponse[SearchResultOutput]:
@@ -385,7 +361,6 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
385
361
  id (string): the id of a search action, found in `response.result.id`
386
362
  limit (integer, optional): the maximum number of results to return, default is 20
387
363
  offset (integer, optional): the position of the first result to return, default is 0
388
- assert_search_restriction (Dict[str, Sequence[str]], optional): Assert the requested search results were queried with the exact same search restrictions, to ensure the results comply to the expected restrictions.
389
364
  verify_consistency (bool): True to verify logs consistency
390
365
  verify_events (bool): True to verify hash events and signatures
391
366
  Raises:
@@ -403,8 +378,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
403
378
  result_res: PangeaResponse[SearchResultsOutput] = audit.results(
404
379
  id=search_res.result.id,
405
380
  limit=10,
406
- offset=0,
407
- assert_search_restriction={'source': ["monitor"]})
381
+ offset=0)
408
382
  """
409
383
 
410
384
  if limit <= 0: # type: ignore[operator]
@@ -417,7 +391,6 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
417
391
  id=id,
418
392
  limit=limit,
419
393
  offset=offset,
420
- assert_search_restriction=assert_search_restriction,
421
394
  )
422
395
  response = await self.request.post("v1/results", SearchResultOutput, data=input.dict(exclude_none=True))
423
396
  if verify_consistency and response.result is not None:
@@ -425,107 +398,6 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
425
398
 
426
399
  return self.handle_results_response(response, verify_consistency, verify_events)
427
400
 
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
-
529
401
  async def root(self, tree_size: Optional[int] = None) -> PangeaResponse[RootResult]:
530
402
  """
531
403
  Tamperproof verification
@@ -551,10 +423,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
551
423
  return await self.request.post("v1/root", RootResult, data=input.dict(exclude_none=True))
552
424
 
553
425
  async def download_results(
554
- self,
555
- result_id: Optional[str] = None,
556
- format: DownloadFormat = DownloadFormat.CSV,
557
- request_id: Optional[str] = None,
426
+ self, result_id: str, format: Optional[DownloadFormat] = None
558
427
  ) -> PangeaResponse[DownloadResult]:
559
428
  """
560
429
  Download search results
@@ -566,7 +435,6 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
566
435
  Args:
567
436
  result_id: ID returned by the search API.
568
437
  format: Format for the records.
569
- request_id: ID returned by the export API.
570
438
 
571
439
  Returns:
572
440
  URL where search results can be downloaded.
@@ -582,10 +450,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
582
450
  )
583
451
  """
584
452
 
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)
453
+ input = DownloadRequest(result_id=result_id, format=format)
589
454
  return await self.request.post("v1/download_results", DownloadResult, data=input.dict(exclude_none=True))
590
455
 
591
456
  async def update_published_roots(self, result: SearchResultOutput):
@@ -1,12 +1,10 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
- from __future__ import annotations
4
3
 
5
4
  from typing import Dict, List, Optional, Union
6
5
 
7
6
  import pangea.services.authn.models as m
8
7
  from pangea.asyncio.services.base import ServiceBaseAsync
9
- from pangea.config import PangeaConfig
10
8
  from pangea.response import PangeaResponse
11
9
 
12
10
  SERVICE_NAME = "authn"
@@ -39,24 +37,10 @@ class AuthNAsync(ServiceBaseAsync):
39
37
 
40
38
  def __init__(
41
39
  self,
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
- """
40
+ token,
41
+ config=None,
42
+ logger_name="pangea",
43
+ ):
60
44
  super().__init__(token, config, logger_name=logger_name)
61
45
  self.user = AuthNAsync.UserAsync(token, config, logger_name=logger_name)
62
46
  self.flow = AuthNAsync.FlowAsync(token, config, logger_name=logger_name)
@@ -69,10 +53,10 @@ class AuthNAsync(ServiceBaseAsync):
69
53
 
70
54
  def __init__(
71
55
  self,
72
- token: str,
73
- config: PangeaConfig | None = None,
74
- logger_name: str = "pangea",
75
- ) -> None:
56
+ token,
57
+ config=None,
58
+ logger_name="pangea",
59
+ ):
76
60
  super().__init__(token, config, logger_name=logger_name)
77
61
 
78
62
  async def invalidate(self, session_id: str) -> PangeaResponse[m.SessionInvalidateResult]:
@@ -164,10 +148,10 @@ class AuthNAsync(ServiceBaseAsync):
164
148
 
165
149
  def __init__(
166
150
  self,
167
- token: str,
168
- config: PangeaConfig | None = None,
169
- logger_name: str = "pangea",
170
- ) -> None:
151
+ token,
152
+ config=None,
153
+ logger_name="pangea",
154
+ ):
171
155
  super().__init__(token, config, logger_name=logger_name)
172
156
  self.session = AuthNAsync.ClientAsync.SessionAsync(token, config, logger_name=logger_name)
173
157
  self.password = AuthNAsync.ClientAsync.PasswordAsync(token, config, logger_name=logger_name)
@@ -224,10 +208,10 @@ class AuthNAsync(ServiceBaseAsync):
224
208
 
225
209
  def __init__(
226
210
  self,
227
- token: str,
228
- config: PangeaConfig | None = None,
229
- logger_name: str = "pangea",
230
- ) -> None:
211
+ token,
212
+ config=None,
213
+ logger_name="pangea",
214
+ ):
231
215
  super().__init__(token, config, logger_name=logger_name)
232
216
 
233
217
  async def invalidate(self, token: str, session_id: str) -> PangeaResponse[m.ClientSessionInvalidateResult]:
@@ -359,10 +343,10 @@ class AuthNAsync(ServiceBaseAsync):
359
343
 
360
344
  def __init__(
361
345
  self,
362
- token: str,
363
- config: PangeaConfig | None = None,
364
- logger_name: str = "pangea",
365
- ) -> None:
346
+ token,
347
+ config=None,
348
+ logger_name="pangea",
349
+ ):
366
350
  super().__init__(token, config, logger_name=logger_name)
367
351
 
368
352
  async def change(
@@ -400,10 +384,10 @@ class AuthNAsync(ServiceBaseAsync):
400
384
 
401
385
  def __init__(
402
386
  self,
403
- token: str,
404
- config: PangeaConfig | None = None,
405
- logger_name: str = "pangea",
406
- ) -> None:
387
+ token,
388
+ config=None,
389
+ logger_name="pangea",
390
+ ):
407
391
  super().__init__(token, config, logger_name=logger_name)
408
392
 
409
393
  async def check(self, token: str) -> PangeaResponse[m.ClientTokenCheckResult]:
@@ -437,10 +421,10 @@ class AuthNAsync(ServiceBaseAsync):
437
421
 
438
422
  def __init__(
439
423
  self,
440
- token: str,
441
- config: PangeaConfig | None = None,
442
- logger_name: str = "pangea",
443
- ) -> None:
424
+ token,
425
+ config=None,
426
+ logger_name="pangea",
427
+ ):
444
428
  super().__init__(token, config, logger_name=logger_name)
445
429
  self.profile = AuthNAsync.UserAsync.ProfileAsync(token, config, logger_name=logger_name)
446
430
  self.authenticators = AuthNAsync.UserAsync.AuthenticatorsAsync(token, config, logger_name=logger_name)
@@ -631,10 +615,10 @@ class AuthNAsync(ServiceBaseAsync):
631
615
 
632
616
  def __init__(
633
617
  self,
634
- token: str,
635
- config: PangeaConfig | None = None,
636
- logger_name: str = "pangea",
637
- ) -> None:
618
+ token,
619
+ config=None,
620
+ logger_name="pangea",
621
+ ):
638
622
  super().__init__(token, config, logger_name=logger_name)
639
623
 
640
624
  async def list(
@@ -703,10 +687,10 @@ class AuthNAsync(ServiceBaseAsync):
703
687
 
704
688
  def __init__(
705
689
  self,
706
- token: str,
707
- config: PangeaConfig | None = None,
708
- logger_name: str = "pangea",
709
- ) -> None:
690
+ token,
691
+ config=None,
692
+ logger_name="pangea",
693
+ ):
710
694
  super().__init__(token, config, logger_name=logger_name)
711
695
 
712
696
  async def delete(
@@ -774,10 +758,10 @@ class AuthNAsync(ServiceBaseAsync):
774
758
 
775
759
  def __init__(
776
760
  self,
777
- token: str,
778
- config: PangeaConfig | None = None,
779
- logger_name: str = "pangea",
780
- ) -> None:
761
+ token,
762
+ config=None,
763
+ logger_name="pangea",
764
+ ):
781
765
  super().__init__(token, config, logger_name=logger_name)
782
766
 
783
767
  async def get(
@@ -854,10 +838,10 @@ class AuthNAsync(ServiceBaseAsync):
854
838
 
855
839
  def __init__(
856
840
  self,
857
- token: str,
858
- config: PangeaConfig | None = None,
859
- logger_name: str = "pangea",
860
- ) -> None:
841
+ token,
842
+ config=None,
843
+ logger_name="pangea",
844
+ ):
861
845
  super().__init__(token, config, logger_name=logger_name)
862
846
 
863
847
  async def complete(self, flow_id: str) -> PangeaResponse[m.FlowCompleteResult]:
@@ -994,10 +978,10 @@ class AuthNAsync(ServiceBaseAsync):
994
978
 
995
979
  def __init__(
996
980
  self,
997
- token: str,
998
- config: PangeaConfig | None = None,
999
- logger_name: str = "pangea",
1000
- ) -> None:
981
+ token,
982
+ config=None,
983
+ logger_name="pangea",
984
+ ):
1001
985
  super().__init__(token, config, logger_name=logger_name)
1002
986
 
1003
987
  async def create(
@@ -76,7 +76,7 @@ class FileIntelAsync(ServiceBaseAsync):
76
76
  provider: Optional[str] = None,
77
77
  verbose: Optional[bool] = None,
78
78
  raw: Optional[bool] = None,
79
- ) -> PangeaResponse[m.FileReputationBulkResult]:
79
+ ) -> PangeaResponse[m.FileReputationResult]:
80
80
  """
81
81
  Reputation check
82
82
 
@@ -182,7 +182,7 @@ class FileIntelAsync(ServiceBaseAsync):
182
182
  hash = hash_256_filepath(filepath)
183
183
  hashes.append(hash)
184
184
 
185
- return await self.hash_reputation_bulk(
185
+ return await self.hash_reputation_bulk( # type: ignore[return-value]
186
186
  hashes=hashes, hash_type="sha256", verbose=verbose, raw=raw, provider=provider
187
187
  )
188
188
 
@@ -251,7 +251,7 @@ class DomainIntelAsync(ServiceBaseAsync):
251
251
  verbose: Optional[bool] = None,
252
252
  raw: Optional[bool] = None,
253
253
  provider: Optional[str] = None,
254
- ) -> PangeaResponse[m.DomainReputationBulkResult]:
254
+ ) -> PangeaResponse[m.DomainReputationResult]:
255
255
  """
256
256
  Reputation
257
257
 
@@ -373,7 +373,7 @@ class IpIntelAsync(ServiceBaseAsync):
373
373
 
374
374
  async def reputation_bulk(
375
375
  self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
376
- ) -> PangeaResponse[m.IPReputationBulkResult]:
376
+ ) -> PangeaResponse[m.IPReputationResult]:
377
377
  """
378
378
  Reputation
379
379