pangea-sdk 4.4.0__py3-none-any.whl → 5.1.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 CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "4.4.0"
1
+ __version__ = "5.1.0"
2
2
 
3
3
  from pangea.asyncio.request import PangeaRequestAsync
4
4
  from pangea.config import PangeaConfig
pangea/asyncio/request.py CHANGED
@@ -4,12 +4,14 @@ from __future__ import annotations
4
4
 
5
5
  import asyncio
6
6
  import json
7
+ import os
7
8
  import time
8
9
  from typing import Any, Dict, List, Optional, Sequence, Tuple, Type, Union
9
10
 
10
11
  import aiohttp
11
12
  from aiohttp import FormData
12
- from typing_extensions import TypeVar
13
+ from pydantic import BaseModel
14
+ from typing_extensions import Any, TypeVar
13
15
 
14
16
  import pangea.exceptions as pe
15
17
  from pangea.request import MultipartResponse, PangeaRequestBase
@@ -32,7 +34,7 @@ class PangeaRequestAsync(PangeaRequestBase):
32
34
  self,
33
35
  endpoint: str,
34
36
  result_class: Type[TResult],
35
- data: Union[str, Dict] = {},
37
+ data: str | BaseModel | dict[str, Any] | None = None,
36
38
  files: Optional[List[Tuple]] = None,
37
39
  poll_result: bool = True,
38
40
  url: Optional[str] = None,
@@ -47,6 +49,13 @@ class PangeaRequestAsync(PangeaRequestBase):
47
49
  PangeaResponse which contains the response in its entirety and
48
50
  various properties to retrieve individual fields
49
51
  """
52
+
53
+ if isinstance(data, BaseModel):
54
+ data = data.model_dump(exclude_none=True)
55
+
56
+ if data is None:
57
+ data = {}
58
+
50
59
  if url is None:
51
60
  url = self._url(endpoint)
52
61
 
@@ -181,6 +190,7 @@ class PangeaRequestAsync(PangeaRequestBase):
181
190
  "service": self.service,
182
191
  "action": "download_file",
183
192
  "url": url,
193
+ "filename": filename,
184
194
  "status": "start",
185
195
  }
186
196
  )
@@ -209,8 +219,7 @@ class PangeaRequestAsync(PangeaRequestBase):
209
219
  )
210
220
 
211
221
  return AttachedFile(filename=filename, file=await response.read(), content_type=content_type)
212
- else:
213
- raise pe.DownloadFileError(f"Failed to download file. Status: {response.status}", await response.text())
222
+ raise pe.DownloadFileError(f"Failed to download file. Status: {response.status}", await response.text())
214
223
 
215
224
  async def _get_pangea_json(self, reader: aiohttp.multipart.MultipartResponseWrapper) -> Optional[Dict[str, Any]]:
216
225
  # Iterate through parts
@@ -296,6 +305,9 @@ class PangeaRequestAsync(PangeaRequestBase):
296
305
  raise AttributeError("files attribute should have at least 1 file")
297
306
 
298
307
  response = await self.request_presigned_url(endpoint=endpoint, result_class=result_class, data=data)
308
+ if response.success: # This should only happen when uploading a zero bytes file
309
+ return response.raw_response
310
+
299
311
  if response.accepted_result is None:
300
312
  raise pe.PangeaException("No accepted_result field when requesting presigned url")
301
313
  if response.accepted_result.post_url is None:
@@ -315,9 +327,8 @@ class PangeaRequestAsync(PangeaRequestBase):
315
327
  ) -> PangeaResponse:
316
328
  # Send request
317
329
  try:
318
- # This should return 202 (AcceptedRequestException)
319
- resp = await self.post(endpoint=endpoint, result_class=result_class, data=data, poll_result=False)
320
- raise pe.PresignedURLException("Should return 202", resp)
330
+ # This should return 202 (AcceptedRequestException) at least zero size file is sent
331
+ return await self.post(endpoint=endpoint, result_class=result_class, data=data, poll_result=False)
321
332
  except pe.AcceptedRequestException as e:
322
333
  accepted_exception = e
323
334
  except Exception as e:
@@ -369,8 +380,7 @@ class PangeaRequestAsync(PangeaRequestBase):
369
380
 
370
381
  if loop_resp.accepted_result is not None and not loop_resp.accepted_result.has_upload_url:
371
382
  return loop_resp
372
- else:
373
- raise loop_exc
383
+ raise loop_exc
374
384
 
375
385
  async def _handle_queued_result(self, response: PangeaResponse) -> PangeaResponse:
376
386
  if self._queued_retry_enabled and response.http_status == 202:
@@ -6,4 +6,5 @@ from .file_scan import FileScanAsync
6
6
  from .intel import DomainIntelAsync, FileIntelAsync, IpIntelAsync, UrlIntelAsync, UserIntelAsync
7
7
  from .redact import RedactAsync
8
8
  from .sanitize import SanitizeAsync
9
+ from .share import ShareAsync
9
10
  from .vault import VaultAsync