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

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,13 +1,14 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+ from __future__ import annotations
3
4
 
4
5
  from typing import Dict, List, Optional, Union
5
6
 
6
7
  import pangea.services.authn.models as m
8
+ from pangea.asyncio.services.base import ServiceBaseAsync
9
+ from pangea.config import PangeaConfig
7
10
  from pangea.response import PangeaResponse
8
11
 
9
- from .base import ServiceBaseAsync
10
-
11
12
  SERVICE_NAME = "authn"
12
13
 
13
14
 
@@ -38,10 +39,24 @@ class AuthNAsync(ServiceBaseAsync):
38
39
 
39
40
  def __init__(
40
41
  self,
41
- token,
42
- config=None,
43
- logger_name="pangea",
44
- ):
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
+ """
45
60
  super().__init__(token, config, logger_name=logger_name)
46
61
  self.user = AuthNAsync.UserAsync(token, config, logger_name=logger_name)
47
62
  self.flow = AuthNAsync.FlowAsync(token, config, logger_name=logger_name)
@@ -54,10 +69,10 @@ class AuthNAsync(ServiceBaseAsync):
54
69
 
55
70
  def __init__(
56
71
  self,
57
- token,
58
- config=None,
59
- logger_name="pangea",
60
- ):
72
+ token: str,
73
+ config: PangeaConfig | None = None,
74
+ logger_name: str = "pangea",
75
+ ) -> None:
61
76
  super().__init__(token, config, logger_name=logger_name)
62
77
 
63
78
  async def invalidate(self, session_id: str) -> PangeaResponse[m.SessionInvalidateResult]:
@@ -114,6 +129,9 @@ class AuthNAsync(ServiceBaseAsync):
114
129
  Examples:
115
130
  response = authn.session.list()
116
131
  """
132
+ if isinstance(filter, dict):
133
+ filter = m.SessionListFilter(**filter)
134
+
117
135
  input = m.SessionListRequest(filter=filter, last=last, order=order, order_by=order_by, size=size)
118
136
  return await self.request.post("v2/session/list", m.SessionListResults, data=input.dict(exclude_none=True))
119
137
 
@@ -146,10 +164,10 @@ class AuthNAsync(ServiceBaseAsync):
146
164
 
147
165
  def __init__(
148
166
  self,
149
- token,
150
- config=None,
151
- logger_name="pangea",
152
- ):
167
+ token: str,
168
+ config: PangeaConfig | None = None,
169
+ logger_name: str = "pangea",
170
+ ) -> None:
153
171
  super().__init__(token, config, logger_name=logger_name)
154
172
  self.session = AuthNAsync.ClientAsync.SessionAsync(token, config, logger_name=logger_name)
155
173
  self.password = AuthNAsync.ClientAsync.PasswordAsync(token, config, logger_name=logger_name)
@@ -206,10 +224,10 @@ class AuthNAsync(ServiceBaseAsync):
206
224
 
207
225
  def __init__(
208
226
  self,
209
- token,
210
- config=None,
211
- logger_name="pangea",
212
- ):
227
+ token: str,
228
+ config: PangeaConfig | None = None,
229
+ logger_name: str = "pangea",
230
+ ) -> None:
213
231
  super().__init__(token, config, logger_name=logger_name)
214
232
 
215
233
  async def invalidate(self, token: str, session_id: str) -> PangeaResponse[m.ClientSessionInvalidateResult]:
@@ -272,6 +290,9 @@ class AuthNAsync(ServiceBaseAsync):
272
290
  token="ptu_wuk7tvtpswyjtlsx52b7yyi2l7zotv4a",
273
291
  )
274
292
  """
293
+ if isinstance(filter, dict):
294
+ filter = m.SessionListFilter(**filter)
295
+
275
296
  input = m.ClientSessionListRequest(
276
297
  token=token, filter=filter, last=last, order=order, order_by=order_by, size=size
277
298
  )
@@ -338,10 +359,10 @@ class AuthNAsync(ServiceBaseAsync):
338
359
 
339
360
  def __init__(
340
361
  self,
341
- token,
342
- config=None,
343
- logger_name="pangea",
344
- ):
362
+ token: str,
363
+ config: PangeaConfig | None = None,
364
+ logger_name: str = "pangea",
365
+ ) -> None:
345
366
  super().__init__(token, config, logger_name=logger_name)
346
367
 
347
368
  async def change(
@@ -379,10 +400,10 @@ class AuthNAsync(ServiceBaseAsync):
379
400
 
380
401
  def __init__(
381
402
  self,
382
- token,
383
- config=None,
384
- logger_name="pangea",
385
- ):
403
+ token: str,
404
+ config: PangeaConfig | None = None,
405
+ logger_name: str = "pangea",
406
+ ) -> None:
386
407
  super().__init__(token, config, logger_name=logger_name)
387
408
 
388
409
  async def check(self, token: str) -> PangeaResponse[m.ClientTokenCheckResult]:
@@ -416,10 +437,10 @@ class AuthNAsync(ServiceBaseAsync):
416
437
 
417
438
  def __init__(
418
439
  self,
419
- token,
420
- config=None,
421
- logger_name="pangea",
422
- ):
440
+ token: str,
441
+ config: PangeaConfig | None = None,
442
+ logger_name: str = "pangea",
443
+ ) -> None:
423
444
  super().__init__(token, config, logger_name=logger_name)
424
445
  self.profile = AuthNAsync.UserAsync.ProfileAsync(token, config, logger_name=logger_name)
425
446
  self.authenticators = AuthNAsync.UserAsync.AuthenticatorsAsync(token, config, logger_name=logger_name)
@@ -593,6 +614,9 @@ class AuthNAsync(ServiceBaseAsync):
593
614
  Examples:
594
615
  response = authn.user.list()
595
616
  """
617
+ if isinstance(filter, dict):
618
+ filter = m.UserListFilter(**filter)
619
+
596
620
  input = m.UserListRequest(
597
621
  filter=filter,
598
622
  last=last,
@@ -607,10 +631,10 @@ class AuthNAsync(ServiceBaseAsync):
607
631
 
608
632
  def __init__(
609
633
  self,
610
- token,
611
- config=None,
612
- logger_name="pangea",
613
- ):
634
+ token: str,
635
+ config: PangeaConfig | None = None,
636
+ logger_name: str = "pangea",
637
+ ) -> None:
614
638
  super().__init__(token, config, logger_name=logger_name)
615
639
 
616
640
  async def list(
@@ -642,6 +666,9 @@ class AuthNAsync(ServiceBaseAsync):
642
666
  Examples:
643
667
  response = authn.user.invites.list()
644
668
  """
669
+ if isinstance(filter, dict):
670
+ filter = m.UserInviteListFilter(**filter)
671
+
645
672
  input = m.UserInviteListRequest(filter=filter, last=last, order=order, order_by=order_by, size=size)
646
673
  return await self.request.post(
647
674
  "v2/user/invite/list", m.UserInviteListResult, data=input.dict(exclude_none=True)
@@ -676,10 +703,10 @@ class AuthNAsync(ServiceBaseAsync):
676
703
 
677
704
  def __init__(
678
705
  self,
679
- token,
680
- config=None,
681
- logger_name="pangea",
682
- ):
706
+ token: str,
707
+ config: PangeaConfig | None = None,
708
+ logger_name: str = "pangea",
709
+ ) -> None:
683
710
  super().__init__(token, config, logger_name=logger_name)
684
711
 
685
712
  async def delete(
@@ -747,10 +774,10 @@ class AuthNAsync(ServiceBaseAsync):
747
774
 
748
775
  def __init__(
749
776
  self,
750
- token,
751
- config=None,
752
- logger_name="pangea",
753
- ):
777
+ token: str,
778
+ config: PangeaConfig | None = None,
779
+ logger_name: str = "pangea",
780
+ ) -> None:
754
781
  super().__init__(token, config, logger_name=logger_name)
755
782
 
756
783
  async def get(
@@ -827,10 +854,10 @@ class AuthNAsync(ServiceBaseAsync):
827
854
 
828
855
  def __init__(
829
856
  self,
830
- token,
831
- config=None,
832
- logger_name="pangea",
833
- ):
857
+ token: str,
858
+ config: PangeaConfig | None = None,
859
+ logger_name: str = "pangea",
860
+ ) -> None:
834
861
  super().__init__(token, config, logger_name=logger_name)
835
862
 
836
863
  async def complete(self, flow_id: str) -> PangeaResponse[m.FlowCompleteResult]:
@@ -967,10 +994,10 @@ class AuthNAsync(ServiceBaseAsync):
967
994
 
968
995
  def __init__(
969
996
  self,
970
- token,
971
- config=None,
972
- logger_name="pangea",
973
- ):
997
+ token: str,
998
+ config: PangeaConfig | None = None,
999
+ logger_name: str = "pangea",
1000
+ ) -> None:
974
1001
  super().__init__(token, config, logger_name=logger_name)
975
1002
 
976
1003
  async def create(
@@ -1064,6 +1091,8 @@ class AuthNAsync(ServiceBaseAsync):
1064
1091
  Examples:
1065
1092
  response = authn.agreements.list()
1066
1093
  """
1094
+ if isinstance(filter, dict):
1095
+ filter = m.AgreementListFilter(**filter)
1067
1096
 
1068
1097
  input = m.AgreementListRequest(filter=filter, last=last, order=order, order_by=order_by, size=size)
1069
1098
  return await self.request.post(
@@ -0,0 +1,259 @@
1
+ # Copyright 2022 Pangea Cyber Corporation
2
+ # Author: Pangea Cyber Corporation
3
+
4
+ from typing import Dict, List, Optional, Union
5
+
6
+ from pangea.asyncio.services.base import ServiceBaseAsync
7
+ from pangea.response import PangeaResponse
8
+ from pangea.services.authz import (
9
+ CheckRequest,
10
+ CheckResult,
11
+ ItemOrder,
12
+ ListResourcesRequest,
13
+ ListResourcesResult,
14
+ ListSubjectsRequest,
15
+ ListSubjectsResult,
16
+ Resource,
17
+ Subject,
18
+ Tuple,
19
+ TupleCreateRequest,
20
+ TupleCreateResult,
21
+ TupleDeleteRequest,
22
+ TupleDeleteResult,
23
+ TupleListFilter,
24
+ TupleListRequest,
25
+ TupleListResult,
26
+ TupleOrderBy,
27
+ )
28
+
29
+
30
+ class AuthZAsync(ServiceBaseAsync):
31
+ """AuthZ service client. (Beta)
32
+
33
+ Provides methods to interact with the Pangea AuthZ Service.
34
+ Documentation for the AuthZ Service API can be found at
35
+ <https://pangea.cloud/docs/api/authz>. Note that this service is in Beta and
36
+ is subject to change.
37
+
38
+ Examples:
39
+ import os
40
+ from pangea.config import PangeaConfig
41
+ from pangea.services import AuthZ
42
+
43
+ PANGEA_TOKEN = os.getenv("PANGEA_AUTHZ_TOKEN")
44
+
45
+ authz_config = PangeaConfig(domain="aws.us.pangea.cloud")
46
+
47
+ # Setup Pangea AuthZ service client
48
+ authz = AuthZAsync(token=PANGEA_TOKEN, config=authz_config)
49
+ """
50
+
51
+ service_name = "authz"
52
+
53
+ def __init__(self, token: str, config=None, logger_name="pangea", config_id: Optional[str] = None):
54
+ super().__init__(token, config, logger_name, config_id=config_id)
55
+
56
+ async def tuple_create(self, tuples: List[Tuple]) -> PangeaResponse[TupleCreateResult]:
57
+ """Create tuples. (Beta)
58
+
59
+ Create tuples in the AuthZ Service. The request will fail if there is no schema
60
+ or the tuples do not validate against the schema.
61
+ How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
62
+
63
+ Args:
64
+ tuples (List[Tuple]): List of tuples to be created.
65
+
66
+ Raises:
67
+ PangeaAPIException: If an API Error happens.
68
+
69
+ Returns:
70
+ Pangea Response with empty result.
71
+ Available response fields can be found in our
72
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/create).
73
+
74
+ Examples:
75
+ await authz.tuple_create(
76
+ tuples=[
77
+ Tuple(
78
+ resource=Resource(type="file", id="file_1"),
79
+ relation="owner",
80
+ subject=Subject(type="user", id="user_1"),
81
+ )
82
+ ]
83
+ )
84
+ """
85
+
86
+ input_data = TupleCreateRequest(tuples=tuples)
87
+ return await self.request.post("v1/tuple/create", TupleCreateResult, data=input_data.dict(exclude_none=True))
88
+
89
+ async def tuple_list(
90
+ self,
91
+ filter: TupleListFilter,
92
+ size: Optional[int] = None,
93
+ last: Optional[str] = None,
94
+ order: Optional[ItemOrder] = None,
95
+ order_by: Optional[TupleOrderBy] = None,
96
+ ) -> PangeaResponse[TupleListResult]:
97
+ """List tuples. (Beta)
98
+
99
+ Return a paginated list of filtered tuples. The filter is given in terms
100
+ of a tuple. Fill out the fields that you want to filter. If the filter
101
+ is empty it will return all the tuples.
102
+ How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
103
+
104
+ Args:
105
+ filter (TupleListFilter): The filter for listing tuples.
106
+ size (Optional[int]): The size of the result set. Default is None.
107
+ last (Optional[str]): The last token from a previous response. Default is None.
108
+ order (Optional[ItemOrder]): Order results asc(ending) or desc(ending).
109
+ order_by (Optional[TupleOrderBy]): Which field to order results by.
110
+
111
+ Raises:
112
+ PangeaAPIException: If an API Error happens.
113
+
114
+ Returns:
115
+ Pangea Response with a list of tuples and the last token.
116
+ Available response fields can be found in our
117
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/list).
118
+
119
+ Examples:
120
+ await authz.tuple_list(TupleListFilter(subject_type="user", subject_id="user_1"))
121
+ """
122
+ input_data = TupleListRequest(
123
+ filter=filter.dict(exclude_none=True), size=size, last=last, order=order, order_by=order_by
124
+ )
125
+ return await self.request.post("v1/tuple/list", TupleListResult, data=input_data.dict(exclude_none=True))
126
+
127
+ async def tuple_delete(self, tuples: List[Tuple]) -> PangeaResponse[TupleDeleteResult]:
128
+ """Delete tuples. (Beta)
129
+
130
+ Delete tuples in the AuthZ Service.
131
+ How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
132
+
133
+ Args:
134
+ tuples (List[Tuple]): List of tuples to be deleted.
135
+
136
+ Raises:
137
+ PangeaAPIException: If an API Error happens.
138
+
139
+ Returns:
140
+ Pangea Response with empty result.
141
+ Available response fields can be found in our
142
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/delete).
143
+
144
+ Examples:
145
+ await authz.tuple_delete(
146
+ tuples=[
147
+ Tuple(
148
+ resource=Resource(type="file", id="file_1"),
149
+ relation="owner",
150
+ subject=Subject(type="user", id="user_1"),
151
+ )
152
+ ]
153
+ )
154
+ """
155
+
156
+ input_data = TupleDeleteRequest(tuples=tuples)
157
+ return await self.request.post("v1/tuple/delete", TupleDeleteResult, data=input_data.dict(exclude_none=True))
158
+
159
+ async def check(
160
+ self,
161
+ resource: Resource,
162
+ action: str,
163
+ subject: Subject,
164
+ debug: Optional[bool] = None,
165
+ attributes: Optional[Dict[str, Union[int, str]]] = None,
166
+ ) -> PangeaResponse[CheckResult]:
167
+ """Perform a check request. (Beta)
168
+
169
+ Check if a subject has permission to perform an action on the resource.
170
+ How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
171
+
172
+ Args:
173
+ resource (Resource): The resource to check.
174
+ action (str): The action to check.
175
+ subject (Subject): The subject to check.
176
+ debug (Optional[bool]): Setting this value to True will provide a detailed analysis of the check.
177
+ attributes (Optional[Dict[str, Union[int, str]]]): Additional attributes for the check.
178
+
179
+ Raises:
180
+ PangeaAPIException: If an API Error happens.
181
+
182
+ Returns:
183
+ Pangea Response with the result of the check.
184
+ Available response fields can be found in our
185
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/check).
186
+
187
+ Examples:
188
+ await authz.check(
189
+ resource=Resource(type="file", id="file_1"),
190
+ action="update",
191
+ subject=Subject(type="user", id="user_1"),
192
+ debug=True,
193
+ )
194
+ """
195
+
196
+ input_data = CheckRequest(resource=resource, action=action, subject=subject, debug=debug, attributes=attributes)
197
+ return await self.request.post("v1/check", CheckResult, data=input_data.dict(exclude_none=True))
198
+
199
+ async def list_resources(self, type: str, action: str, subject: Subject) -> PangeaResponse[ListResourcesResult]:
200
+ """List resources. (Beta)
201
+
202
+ Given a type, action, and subject, list all the resources in the
203
+ type that the subject has access to the action with.
204
+ How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
205
+
206
+ Args:
207
+ type (str): The type to filter resources.
208
+ action (str): The action to filter resources.
209
+ subject (Subject): The subject to filter resources.
210
+
211
+ Raises:
212
+ PangeaAPIException: If an API Error happens.
213
+
214
+ Returns:
215
+ Pangea Response with a list of resource IDs.
216
+ Available response fields can be found in our
217
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/list-resources).
218
+
219
+ Examples:
220
+ await authz.list_resources(
221
+ type="file",
222
+ action="update",
223
+ subject=Subject(type="user", id="user_1"),
224
+ )
225
+ """
226
+
227
+ input_data = ListResourcesRequest(type=type, action=action, subject=subject)
228
+ return await self.request.post(
229
+ "v1/list-resources", ListResourcesResult, data=input_data.dict(exclude_none=True)
230
+ )
231
+
232
+ async def list_subjects(self, resource: Resource, action: str) -> PangeaResponse[ListSubjectsResult]:
233
+ """List subjects. (Beta)
234
+
235
+ Given a resource and an action, return the list of subjects who have
236
+ access to the action for the given resource.
237
+ How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
238
+
239
+ Args:
240
+ resource (Resource): The resource to filter subjects.
241
+ action (str): The action to filter subjects.
242
+
243
+ Raises:
244
+ PangeaAPIException: If an API Error happens.
245
+
246
+ Returns:
247
+ Pangea Response with a list of subjects.
248
+ Available response fields can be found in our
249
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/list-subjects).
250
+
251
+ Examples:
252
+ await authz.list_subjects(
253
+ resource=Resource(type="file", id="file_1"),
254
+ action="update",
255
+ )
256
+ """
257
+
258
+ input_data = ListSubjectsRequest(resource=resource, action=action)
259
+ return await self.request.post("v1/list-subjects", ListSubjectsResult, data=input_data.dict(exclude_none=True))
@@ -1,18 +1,18 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
3
 
4
- from typing import Optional, Type, Union
4
+ from typing import Dict, Optional, Type, Union
5
5
 
6
6
  from pangea.asyncio.request import PangeaRequestAsync
7
7
  from pangea.exceptions import AcceptedRequestException
8
- from pangea.response import PangeaResponse, PangeaResponseResult
9
- from pangea.services.base import ServiceBase
8
+ from pangea.response import AttachedFile, PangeaResponse, PangeaResponseResult
9
+ from pangea.services.base import PangeaRequest, ServiceBase
10
10
 
11
11
 
12
12
  class ServiceBaseAsync(ServiceBase):
13
13
  @property
14
- def request(self):
15
- if not self._request:
14
+ def request(self) -> PangeaRequestAsync: # type: ignore[override]
15
+ if self._request is None or isinstance(self._request, PangeaRequest):
16
16
  self._request = PangeaRequestAsync(
17
17
  config=self.config,
18
18
  token=self.token,
@@ -28,7 +28,7 @@ class ServiceBaseAsync(ServiceBase):
28
28
  exception: Optional[AcceptedRequestException] = None,
29
29
  response: Optional[PangeaResponse] = None,
30
30
  request_id: Optional[str] = None,
31
- result_class: Union[Type[PangeaResponseResult], dict] = dict, # type: ignore[assignment]
31
+ result_class: Union[Type[PangeaResponseResult], Type[Dict]] = dict,
32
32
  ) -> PangeaResponse:
33
33
  """
34
34
  Poll result
@@ -58,6 +58,9 @@ class ServiceBaseAsync(ServiceBase):
58
58
  else:
59
59
  raise AttributeError("Need to set exception, response or request_id")
60
60
 
61
+ async def download_file(self, url: str, filename: Optional[str] = None) -> AttachedFile: # type: ignore[override]
62
+ return await self.request.download_file(url=url, filename=filename)
63
+
61
64
  async def close(self):
62
65
  await self.request.session.close()
63
66
  # Loop over all attributes to check if they are derived from ServiceBaseAsync and close them
@@ -2,16 +2,15 @@
2
2
  # Author: Pangea Cyber Corporation
3
3
  import io
4
4
  import logging
5
- from typing import Dict, Optional
5
+ from typing import Dict, List, Optional, Tuple
6
6
 
7
7
  import pangea.services.file_scan as m
8
8
  from pangea.asyncio.request import PangeaRequestAsync
9
+ from pangea.asyncio.services.base import ServiceBaseAsync
9
10
  from pangea.request import PangeaConfig
10
11
  from pangea.response import PangeaResponse, TransferMethod
11
12
  from pangea.utils import FileUploadParams, get_file_upload_params
12
13
 
13
- from .base import ServiceBaseAsync
14
-
15
14
 
16
15
  class FileScanAsync(ServiceBaseAsync):
17
16
  """FileScan service client.
@@ -96,7 +95,7 @@ class FileScanAsync(ServiceBaseAsync):
96
95
  size = params.size
97
96
  else:
98
97
  crc, sha, size = None, None, None
99
- files = [("upload", ("filename", file, "application/octet-stream"))]
98
+ files: List[Tuple] = [("upload", ("filename", file, "application/octet-stream"))]
100
99
  else:
101
100
  raise ValueError("Need to set file_path or file arguments")
102
101
 
@@ -4,11 +4,10 @@ import hashlib
4
4
  from typing import List, Optional
5
5
 
6
6
  import pangea.services.intel as m
7
+ from pangea.asyncio.services.base import ServiceBaseAsync
7
8
  from pangea.response import PangeaResponse
8
9
  from pangea.utils import hash_256_filepath
9
10
 
10
- from .base import ServiceBaseAsync
11
-
12
11
 
13
12
  class FileIntelAsync(ServiceBaseAsync):
14
13
  """File Intel service client
@@ -77,7 +76,7 @@ class FileIntelAsync(ServiceBaseAsync):
77
76
  provider: Optional[str] = None,
78
77
  verbose: Optional[bool] = None,
79
78
  raw: Optional[bool] = None,
80
- ) -> PangeaResponse[m.FileReputationResult]:
79
+ ) -> PangeaResponse[m.FileReputationBulkResult]:
81
80
  """
82
81
  Reputation check
83
82
 
@@ -183,7 +182,7 @@ class FileIntelAsync(ServiceBaseAsync):
183
182
  hash = hash_256_filepath(filepath)
184
183
  hashes.append(hash)
185
184
 
186
- return await self.hash_reputation_bulk( # type: ignore[return-value]
185
+ return await self.hash_reputation_bulk(
187
186
  hashes=hashes, hash_type="sha256", verbose=verbose, raw=raw, provider=provider
188
187
  )
189
188
 
@@ -252,7 +251,7 @@ class DomainIntelAsync(ServiceBaseAsync):
252
251
  verbose: Optional[bool] = None,
253
252
  raw: Optional[bool] = None,
254
253
  provider: Optional[str] = None,
255
- ) -> PangeaResponse[m.DomainReputationResult]:
254
+ ) -> PangeaResponse[m.DomainReputationBulkResult]:
256
255
  """
257
256
  Reputation
258
257
 
@@ -374,7 +373,7 @@ class IpIntelAsync(ServiceBaseAsync):
374
373
 
375
374
  async def reputation_bulk(
376
375
  self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
377
- ) -> PangeaResponse[m.IPReputationResult]:
376
+ ) -> PangeaResponse[m.IPReputationBulkResult]:
378
377
  """
379
378
  Reputation
380
379
 
@@ -1,13 +1,14 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+ from __future__ import annotations
3
4
 
4
5
  from typing import Dict, List, Optional, Union
5
6
 
6
7
  import pangea.services.redact as m
8
+ from pangea.asyncio.services.base import ServiceBaseAsync
9
+ from pangea.config import PangeaConfig
7
10
  from pangea.response import PangeaResponse
8
11
 
9
- from .base import ServiceBaseAsync
10
-
11
12
 
12
13
  class RedactAsync(ServiceBaseAsync):
13
14
  """Redact service client.
@@ -36,7 +37,24 @@ class RedactAsync(ServiceBaseAsync):
36
37
 
37
38
  service_name = "redact"
38
39
 
39
- def __init__(self, token, config=None, logger_name="pangea", config_id: Optional[str] = None):
40
+ def __init__(
41
+ self, token: str, config: PangeaConfig | None = None, logger_name: str = "pangea", config_id: str | None = None
42
+ ) -> None:
43
+ """
44
+ Redact client
45
+
46
+ Initializes a new Redact client.
47
+
48
+ Args:
49
+ token: Pangea API token.
50
+ config: Configuration.
51
+ logger_name: Logger name.
52
+
53
+ Examples:
54
+ config = PangeaConfig(domain="pangea_domain")
55
+ redact = RedactAsync(token="pangea_token", config=config)
56
+ """
57
+
40
58
  super().__init__(token, config, logger_name, config_id=config_id)
41
59
 
42
60
  async def redact(