pangea-sdk 3.3.0__tar.gz → 3.4.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/PKG-INFO +1 -1
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/__init__.py +1 -1
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/asyncio/request.py +15 -18
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/asyncio/services/file_scan.py +12 -12
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/request.py +11 -12
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/response.py +11 -3
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/file_scan.py +17 -16
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pyproject.toml +1 -1
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/README.md +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/asyncio/services/__init__.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/asyncio/services/audit.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/asyncio/services/authn.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/asyncio/services/base.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/asyncio/services/embargo.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/asyncio/services/intel.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/asyncio/services/redact.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/asyncio/services/vault.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/audit_logger.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/config.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/deep_verify.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/deprecated.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/dump_audit.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/exceptions.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/__init__.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/audit/audit.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/audit/exceptions.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/audit/models.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/audit/signing.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/audit/util.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/authn/authn.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/authn/models.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/base.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/embargo.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/intel.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/redact.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/vault/models/asymmetric.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/vault/models/common.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/vault/models/secret.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/vault/models/symmetric.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/services/vault/vault.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/tools.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/utils.py +0 -0
- {pangea_sdk-3.3.0 → pangea_sdk-3.4.0}/pangea/verify_audit.py +0 -0
@@ -53,11 +53,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
53
53
|
|
54
54
|
transfer_method = data.get("transfer_method", None)
|
55
55
|
|
56
|
-
if (
|
57
|
-
files is not None
|
58
|
-
and type(data) is dict
|
59
|
-
and (transfer_method == TransferMethod.DIRECT.value or transfer_method == TransferMethod.POST_URL.value)
|
60
|
-
):
|
56
|
+
if files is not None and type(data) is dict and (transfer_method == TransferMethod.POST_URL.value):
|
61
57
|
requests_response = await self._full_post_presigned_url(
|
62
58
|
endpoint, result_class=result_class, data=data, files=files
|
63
59
|
)
|
@@ -66,9 +62,10 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
66
62
|
url, headers=self._headers(), data=data, files=files, presigned_url_post=False
|
67
63
|
)
|
68
64
|
|
69
|
-
|
70
|
-
|
71
|
-
|
65
|
+
json_resp = await requests_response.json()
|
66
|
+
self.logger.debug(json.dumps({"service": self.service, "action": "post", "url": url, "response": json_resp}))
|
67
|
+
|
68
|
+
pangea_response = PangeaResponse(requests_response, result_class=result_class, json=json_resp)
|
72
69
|
if poll_result:
|
73
70
|
pangea_response = await self._handle_queued_result(pangea_response)
|
74
71
|
|
@@ -143,13 +140,13 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
143
140
|
resp = await self._http_put(url=url, files=files)
|
144
141
|
self.logger.debug(
|
145
142
|
json.dumps(
|
146
|
-
{"service": self.service, "action": "put presigned", "url": url, "response": resp.text},
|
143
|
+
{"service": self.service, "action": "put presigned", "url": url, "response": await resp.text()},
|
147
144
|
default=default_encoder,
|
148
145
|
)
|
149
146
|
)
|
150
147
|
|
151
|
-
if resp.
|
152
|
-
raise pe.PresignedUploadError(f"presigned PUT failure: {resp.
|
148
|
+
if resp.status < 200 or resp.status >= 300:
|
149
|
+
raise pe.PresignedUploadError(f"presigned PUT failure: {resp.status}", await resp.text())
|
153
150
|
|
154
151
|
async def _http_post(
|
155
152
|
self,
|
@@ -196,7 +193,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
196
193
|
form = FormData()
|
197
194
|
name, value = files[0]
|
198
195
|
form.add_field(name, value[1], filename=value[0], content_type=value[2])
|
199
|
-
return self.session.put(url, headers=headers, data=form)
|
196
|
+
return await self.session.put(url, headers=headers, data=form)
|
200
197
|
|
201
198
|
async def _full_post_presigned_url(
|
202
199
|
self,
|
@@ -209,8 +206,8 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
209
206
|
raise AttributeError("files attribute should have at least 1 file")
|
210
207
|
|
211
208
|
response = await self.request_presigned_url(endpoint=endpoint, result_class=result_class, data=data)
|
212
|
-
data_to_presigned = response.accepted_result.
|
213
|
-
presigned_url = response.accepted_result.
|
209
|
+
data_to_presigned = response.accepted_result.post_form_data
|
210
|
+
presigned_url = response.accepted_result.post_url
|
214
211
|
|
215
212
|
await self.post_presigned_url(url=presigned_url, data=data_to_presigned, files=files)
|
216
213
|
return response.raw_response
|
@@ -231,14 +228,14 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
231
228
|
except Exception as e:
|
232
229
|
raise e
|
233
230
|
|
234
|
-
# Receive 202
|
231
|
+
# Receive 202
|
235
232
|
return await self._poll_presigned_url(accepted_exception.response)
|
236
233
|
|
237
234
|
async def _poll_presigned_url(self, response: PangeaResponse) -> AcceptedResult:
|
238
235
|
if response.http_status != 202:
|
239
236
|
raise AttributeError("Response should be 202")
|
240
237
|
|
241
|
-
if response.accepted_result.
|
238
|
+
if response.accepted_result is not None and response.accepted_result.has_upload_url:
|
242
239
|
return response
|
243
240
|
|
244
241
|
self.logger.debug(json.dumps({"service": self.service, "action": "poll_presigned_url", "step": "start"}))
|
@@ -248,7 +245,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
248
245
|
|
249
246
|
while (
|
250
247
|
loop_resp.accepted_result is not None
|
251
|
-
and not loop_resp.accepted_result.
|
248
|
+
and not loop_resp.accepted_result.has_upload_url
|
252
249
|
and not self._reach_timeout(start)
|
253
250
|
):
|
254
251
|
await asyncio.sleep(self._get_delay(retry_count, start))
|
@@ -275,7 +272,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
275
272
|
|
276
273
|
self.logger.debug(json.dumps({"service": self.service, "action": "poll_presigned_url", "step": "exit"}))
|
277
274
|
|
278
|
-
if loop_resp.accepted_result is not None and not loop_resp.accepted_result.
|
275
|
+
if loop_resp.accepted_result is not None and not loop_resp.accepted_result.has_upload_url:
|
279
276
|
return loop_resp
|
280
277
|
else:
|
281
278
|
raise loop_exc
|
@@ -49,7 +49,8 @@ class FileScanAsync(ServiceBaseAsync):
|
|
49
49
|
raw: Optional[bool] = None,
|
50
50
|
provider: Optional[str] = None,
|
51
51
|
sync_call: bool = True,
|
52
|
-
transfer_method: TransferMethod = TransferMethod.
|
52
|
+
transfer_method: TransferMethod = TransferMethod.POST_URL,
|
53
|
+
source_url: Optional[str] = None,
|
53
54
|
) -> PangeaResponse[m.FileScanResult]:
|
54
55
|
"""
|
55
56
|
Scan
|
@@ -88,7 +89,7 @@ class FileScanAsync(ServiceBaseAsync):
|
|
88
89
|
if file or file_path:
|
89
90
|
if file_path:
|
90
91
|
file = open(file_path, "rb")
|
91
|
-
if transfer_method == TransferMethod.
|
92
|
+
if transfer_method == TransferMethod.POST_URL:
|
92
93
|
params = get_file_upload_params(file)
|
93
94
|
crc = params.crc_hex
|
94
95
|
sha = params.sha256_hex
|
@@ -103,10 +104,11 @@ class FileScanAsync(ServiceBaseAsync):
|
|
103
104
|
verbose=verbose,
|
104
105
|
raw=raw,
|
105
106
|
provider=provider,
|
106
|
-
|
107
|
-
|
108
|
-
|
107
|
+
crc32c=crc,
|
108
|
+
sha256=sha,
|
109
|
+
size=size,
|
109
110
|
transfer_method=transfer_method,
|
111
|
+
source_url=source_url,
|
110
112
|
)
|
111
113
|
data = input.dict(exclude_none=True)
|
112
114
|
return await self.request.post("v1/scan", m.FileScanResult, data=data, files=files, poll_result=sync_call)
|
@@ -125,12 +127,10 @@ class FileScanAsync(ServiceBaseAsync):
|
|
125
127
|
provider=provider,
|
126
128
|
transfer_method=transfer_method,
|
127
129
|
)
|
128
|
-
if params is not None and (
|
129
|
-
|
130
|
-
|
131
|
-
input.
|
132
|
-
input.transfer_sha256 = params.sha256_hex
|
133
|
-
input.transfer_size = params.size
|
130
|
+
if params is not None and (transfer_method == TransferMethod.POST_URL):
|
131
|
+
input.crc32c = params.crc_hex
|
132
|
+
input.sha256 = params.sha256_hex
|
133
|
+
input.size = params.size
|
134
134
|
|
135
135
|
data = input.dict(exclude_none=True)
|
136
136
|
return await self.request.request_presigned_url("v1/scan", m.FileScanResult, data=data)
|
@@ -156,7 +156,7 @@ class FileUploaderAsync:
|
|
156
156
|
if transfer_method == TransferMethod.PUT_URL:
|
157
157
|
files = [("file", ("filename", file, "application/octet-stream"))]
|
158
158
|
await self._request.put_presigned_url(url=url, files=files)
|
159
|
-
elif transfer_method == TransferMethod.POST_URL
|
159
|
+
elif transfer_method == TransferMethod.POST_URL:
|
160
160
|
files = [("file", ("filename", file, "application/octet-stream"))]
|
161
161
|
await self._request.post_presigned_url(url=url, data=file_details, files=files)
|
162
162
|
else:
|
@@ -205,11 +205,7 @@ class PangeaRequest(PangeaRequestBase):
|
|
205
205
|
|
206
206
|
transfer_method = data.get("transfer_method", None)
|
207
207
|
|
208
|
-
if (
|
209
|
-
files is not None
|
210
|
-
and type(data) is dict
|
211
|
-
and (transfer_method == TransferMethod.DIRECT.value or transfer_method == TransferMethod.POST_URL.value)
|
212
|
-
):
|
208
|
+
if files is not None and type(data) is dict and (transfer_method == TransferMethod.POST_URL.value):
|
213
209
|
requests_response = self._full_post_presigned_url(
|
214
210
|
endpoint, result_class=result_class, data=data, files=files
|
215
211
|
)
|
@@ -218,7 +214,10 @@ class PangeaRequest(PangeaRequestBase):
|
|
218
214
|
url, headers=self._headers(), data=data, files=files, multipart_post=True
|
219
215
|
)
|
220
216
|
|
221
|
-
|
217
|
+
json_resp = requests_response.json()
|
218
|
+
self.logger.debug(json.dumps({"service": self.service, "action": "post", "url": url, "response": json_resp}))
|
219
|
+
|
220
|
+
pangea_response = PangeaResponse(requests_response, result_class=result_class, json=json_resp)
|
222
221
|
if poll_result:
|
223
222
|
pangea_response = self._handle_queued_result(pangea_response)
|
224
223
|
|
@@ -287,7 +286,7 @@ class PangeaRequest(PangeaRequestBase):
|
|
287
286
|
except Exception as e:
|
288
287
|
raise e
|
289
288
|
|
290
|
-
# Receive 202
|
289
|
+
# Receive 202
|
291
290
|
return self._poll_presigned_url(accepted_exception.response)
|
292
291
|
|
293
292
|
def post_presigned_url(self, url: str, data: Dict, files: List[Tuple]):
|
@@ -382,8 +381,8 @@ class PangeaRequest(PangeaRequestBase):
|
|
382
381
|
raise AttributeError("files attribute should have at least 1 file")
|
383
382
|
|
384
383
|
response = self.request_presigned_url(endpoint=endpoint, result_class=result_class, data=data)
|
385
|
-
data_to_presigned = response.accepted_result.
|
386
|
-
presigned_url = response.accepted_result.
|
384
|
+
data_to_presigned = response.accepted_result.post_form_data
|
385
|
+
presigned_url = response.accepted_result.post_url
|
387
386
|
|
388
387
|
self.post_presigned_url(url=presigned_url, data=data_to_presigned, files=files)
|
389
388
|
return response.raw_response
|
@@ -416,7 +415,7 @@ class PangeaRequest(PangeaRequestBase):
|
|
416
415
|
if response.http_status != 202:
|
417
416
|
raise AttributeError("Response should be 202")
|
418
417
|
|
419
|
-
if response.accepted_result.
|
418
|
+
if response.accepted_result is not None and response.accepted_result.has_upload_url:
|
420
419
|
return response
|
421
420
|
|
422
421
|
self.logger.debug(json.dumps({"service": self.service, "action": "poll_presigned_url", "step": "start"}))
|
@@ -426,7 +425,7 @@ class PangeaRequest(PangeaRequestBase):
|
|
426
425
|
|
427
426
|
while (
|
428
427
|
loop_resp.accepted_result is not None
|
429
|
-
and not loop_resp.accepted_result.
|
428
|
+
and not loop_resp.accepted_result.has_upload_url
|
430
429
|
and not self._reach_timeout(start)
|
431
430
|
):
|
432
431
|
time.sleep(self._get_delay(retry_count, start))
|
@@ -453,7 +452,7 @@ class PangeaRequest(PangeaRequestBase):
|
|
453
452
|
|
454
453
|
self.logger.debug(json.dumps({"service": self.service, "action": "poll_presigned_url", "step": "exit"}))
|
455
454
|
|
456
|
-
if loop_resp.accepted_result is not None and not loop_resp.accepted_result.
|
455
|
+
if loop_resp.accepted_result is not None and not loop_resp.accepted_result.has_upload_url:
|
457
456
|
return loop_resp
|
458
457
|
else:
|
459
458
|
raise loop_exc
|
@@ -13,11 +13,10 @@ T = TypeVar("T")
|
|
13
13
|
|
14
14
|
|
15
15
|
class TransferMethod(str, enum.Enum):
|
16
|
-
DIRECT = "post-url" # deprecated, use POST_URL instead
|
17
16
|
MULTIPART = "multipart"
|
18
17
|
POST_URL = "post-url"
|
19
18
|
PUT_URL = "put-url"
|
20
|
-
|
19
|
+
SOURCE_URL = "source-url"
|
21
20
|
|
22
21
|
def __str__(self):
|
23
22
|
return str(self.value)
|
@@ -79,7 +78,16 @@ class AcceptedStatus(APIResponseModel):
|
|
79
78
|
|
80
79
|
|
81
80
|
class AcceptedResult(PangeaResponseResult):
|
82
|
-
|
81
|
+
ttl_mins: int
|
82
|
+
retry_counter: int
|
83
|
+
location: str
|
84
|
+
post_url: Optional[str] = None
|
85
|
+
post_form_data: Dict[str, Any] = {}
|
86
|
+
put_url: Optional[str] = None
|
87
|
+
|
88
|
+
@property
|
89
|
+
def has_upload_url(self) -> bool:
|
90
|
+
return self.post_url is not None or self.put_url is not None
|
83
91
|
|
84
92
|
|
85
93
|
class PangeaError(PangeaResponseResult):
|
@@ -23,10 +23,11 @@ class FileScanRequest(APIRequestModel):
|
|
23
23
|
verbose: Optional[bool] = None
|
24
24
|
raw: Optional[bool] = None
|
25
25
|
provider: Optional[str] = None
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
size: Optional[int] = None
|
27
|
+
crc32c: Optional[str] = None
|
28
|
+
sha256: Optional[str] = None
|
29
|
+
source_url: Optional[str] = None
|
30
|
+
transfer_method: TransferMethod = TransferMethod.POST_URL
|
30
31
|
|
31
32
|
|
32
33
|
class FileScanData(PangeaResponseResult):
|
@@ -81,7 +82,8 @@ class FileScan(ServiceBase):
|
|
81
82
|
raw: Optional[bool] = None,
|
82
83
|
provider: Optional[str] = None,
|
83
84
|
sync_call: bool = True,
|
84
|
-
transfer_method: TransferMethod = TransferMethod.
|
85
|
+
transfer_method: TransferMethod = TransferMethod.POST_URL,
|
86
|
+
source_url: Optional[str] = None,
|
85
87
|
) -> PangeaResponse[FileScanResult]:
|
86
88
|
"""
|
87
89
|
Scan
|
@@ -120,7 +122,7 @@ class FileScan(ServiceBase):
|
|
120
122
|
if file or file_path:
|
121
123
|
if file_path:
|
122
124
|
file = open(file_path, "rb")
|
123
|
-
if transfer_method == TransferMethod.
|
125
|
+
if transfer_method == TransferMethod.POST_URL:
|
124
126
|
params = get_file_upload_params(file)
|
125
127
|
crc = params.crc_hex
|
126
128
|
sha = params.sha256_hex
|
@@ -135,10 +137,11 @@ class FileScan(ServiceBase):
|
|
135
137
|
verbose=verbose,
|
136
138
|
raw=raw,
|
137
139
|
provider=provider,
|
138
|
-
|
139
|
-
|
140
|
-
|
140
|
+
crc32c=crc,
|
141
|
+
sha256=sha,
|
142
|
+
size=size,
|
141
143
|
transfer_method=transfer_method,
|
144
|
+
source_url=source_url,
|
142
145
|
)
|
143
146
|
data = input.dict(exclude_none=True)
|
144
147
|
return self.request.post("v1/scan", FileScanResult, data=data, files=files, poll_result=sync_call)
|
@@ -157,12 +160,10 @@ class FileScan(ServiceBase):
|
|
157
160
|
provider=provider,
|
158
161
|
transfer_method=transfer_method,
|
159
162
|
)
|
160
|
-
if params is not None and (
|
161
|
-
|
162
|
-
|
163
|
-
input.
|
164
|
-
input.transfer_sha256 = params.sha256_hex
|
165
|
-
input.transfer_size = params.size
|
163
|
+
if params is not None and (transfer_method == TransferMethod.POST_URL):
|
164
|
+
input.crc32c = params.crc_hex
|
165
|
+
input.sha256 = params.sha256_hex
|
166
|
+
input.size = params.size
|
166
167
|
|
167
168
|
data = input.dict(exclude_none=True)
|
168
169
|
return self.request.request_presigned_url("v1/scan", FileScanResult, data=data)
|
@@ -188,7 +189,7 @@ class FileUploader:
|
|
188
189
|
if transfer_method == TransferMethod.PUT_URL:
|
189
190
|
files = [("file", ("filename", file, "application/octet-stream"))]
|
190
191
|
self._request.put_presigned_url(url=url, files=files)
|
191
|
-
elif transfer_method == TransferMethod.POST_URL
|
192
|
+
elif transfer_method == TransferMethod.POST_URL:
|
192
193
|
files = [("file", ("filename", file, "application/octet-stream"))]
|
193
194
|
self._request.post_presigned_url(url=url, data=file_details, files=files)
|
194
195
|
else:
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|