pangea-sdk 3.3.0__py3-none-any.whl → 3.4.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 -1
- pangea/asyncio/request.py +15 -18
- pangea/asyncio/services/file_scan.py +12 -12
- pangea/request.py +11 -12
- pangea/response.py +11 -3
- pangea/services/file_scan.py +17 -16
- {pangea_sdk-3.3.0.dist-info → pangea_sdk-3.4.0.dist-info}/METADATA +1 -1
- {pangea_sdk-3.3.0.dist-info → pangea_sdk-3.4.0.dist-info}/RECORD +9 -9
- {pangea_sdk-3.3.0.dist-info → pangea_sdk-3.4.0.dist-info}/WHEEL +0 -0
pangea/__init__.py
CHANGED
pangea/asyncio/request.py
CHANGED
@@ -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:
|
pangea/request.py
CHANGED
@@ -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
|
pangea/response.py
CHANGED
@@ -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):
|
pangea/services/file_scan.py
CHANGED
@@ -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:
|
@@ -1,11 +1,11 @@
|
|
1
|
-
pangea/__init__.py,sha256=
|
2
|
-
pangea/asyncio/request.py,sha256=
|
1
|
+
pangea/__init__.py,sha256=IdKL3uBCgPwFlLeZHTLAAY32MvYJBkmSYEBKIOoYXzI,200
|
2
|
+
pangea/asyncio/request.py,sha256=HXD0LscN0lfGoN9Nu0C8fMMkAZT7LLg2UotbD-A57q4,12628
|
3
3
|
pangea/asyncio/services/__init__.py,sha256=_CEDza6E9VmEs6d_vubWetfeqTogH7UxT7XrTVRw4Mo,290
|
4
4
|
pangea/asyncio/services/audit.py,sha256=xHvz5ReJpmk_StK3mr_uDqCI80J6Aj7-EglEBWS0Qqc,16480
|
5
5
|
pangea/asyncio/services/authn.py,sha256=HssvrZ3fr2oP5sgYBj1Rr5Yf-fKiHhrWTue5LOAeyOk,43288
|
6
6
|
pangea/asyncio/services/base.py,sha256=hmdY5-IS_H2WGMeVfzotn11Z1c2B2iJTHi4USBbmptA,2304
|
7
7
|
pangea/asyncio/services/embargo.py,sha256=8WguyWZUaGVwGpNzic5h8QzLueirA9WpBBik4mpCTeA,3056
|
8
|
-
pangea/asyncio/services/file_scan.py,sha256=
|
8
|
+
pangea/asyncio/services/file_scan.py,sha256=o_6Cddk8bXXlh4Aj_DUQJYlE9Q6U0XGPlZxML88PTfw,6151
|
9
9
|
pangea/asyncio/services/intel.py,sha256=LdJSxCohXsI4Vk8bG74jXTBYAL9N45lb5LIX7nBXqLI,22248
|
10
10
|
pangea/asyncio/services/redact.py,sha256=W9eKMw1XyY6tgRudRrtuCpyQYhgttvmsYngoiMld0C4,5152
|
11
11
|
pangea/asyncio/services/vault.py,sha256=JhxUdmPNYZzp3eiAQFR6vsfyS9L3ddKWes-Cv7rj2ow,43425
|
@@ -15,8 +15,8 @@ pangea/deep_verify.py,sha256=WiA_2gqtrSCQYoTMKX9ILlNgnknsH4UxZpJXLVG2uyc,8343
|
|
15
15
|
pangea/deprecated.py,sha256=IjFYEVvY1E0ld0SMkEYC1o62MAleX3nnT1If2dFVbHo,608
|
16
16
|
pangea/dump_audit.py,sha256=Ws0KuZyHoaySsQ2lq9EKK2iw65O8x4zL1Mii0ChDh0k,6511
|
17
17
|
pangea/exceptions.py,sha256=JMx_Dym7W2cgcPSHN4bz9Rlrm-3BZGNpIYu3VBXZLBU,5277
|
18
|
-
pangea/request.py,sha256=
|
19
|
-
pangea/response.py,sha256=
|
18
|
+
pangea/request.py,sha256=GShc12dltLSapfayHChnHEmL9l4feyYCA-O-PQ4k_VY,18641
|
19
|
+
pangea/response.py,sha256=8cA08NjP_2jIq73lybBaBK0N7XnYLd0f9rOHNcnESg4,5552
|
20
20
|
pangea/services/__init__.py,sha256=auqKaEAOLiazHCzOQVwrUwd2ABFw_bF-ptoOq1bpa68,253
|
21
21
|
pangea/services/audit/audit.py,sha256=50zkQE2HQ0cQtFroFSVjUxX1M4RQsf6pBUeMidSkEHI,30295
|
22
22
|
pangea/services/audit/exceptions.py,sha256=CVdaQZCvQKx1n-iIjWz5wnStUGU6cXDwKqe7MoijAXk,451
|
@@ -27,7 +27,7 @@ pangea/services/authn/authn.py,sha256=sGQUPQ8VLEMtu8AkEhWPyY6Q6AxCsfrX-XNUzkC-o1
|
|
27
27
|
pangea/services/authn/models.py,sha256=V-hj1KfbSuaWJMVgd-Q3fWTsnbj3EdPumnzXtjHOR8g,18150
|
28
28
|
pangea/services/base.py,sha256=bRSuuhLv6iQrPVjhasOjTBqOgxTRRhCD204v3tNjVOE,2731
|
29
29
|
pangea/services/embargo.py,sha256=F3jx7SbElnjhbDEUR3oHfWsQ8G8zf_kfp6_q1_vmOIc,3871
|
30
|
-
pangea/services/file_scan.py,sha256=
|
30
|
+
pangea/services/file_scan.py,sha256=iwqvJcaNE1nJN4VpLcYKtgWFfgnbLLxnbUylhIdEPTk,6882
|
31
31
|
pangea/services/intel.py,sha256=oTvTxCtdnoaZRlt0anUKnkRT2FVfc9LG8ftDIX09jHk,30399
|
32
32
|
pangea/services/redact.py,sha256=vH4sg_t8MnoSjSY-F42JZhe8EfRmVCclslDN7U1hNP4,7756
|
33
33
|
pangea/services/vault/models/asymmetric.py,sha256=ac2Exc66elXxO-HxBqtvLPQWNI7y_00kb6SVqBPKecA,1450
|
@@ -38,6 +38,6 @@ pangea/services/vault/vault.py,sha256=t3KU59FjUfVawbMZt7A51cDQoyapftChdihTqllVrT
|
|
38
38
|
pangea/tools.py,sha256=A9gkHpAkECwqnUKA-O09vG-n6Gmq2g_LYr61BUs-n54,6403
|
39
39
|
pangea/utils.py,sha256=09dHX9CKmyKNWccSF2z7LyCYYYduZ9AWP6D5Ylnfty8,3360
|
40
40
|
pangea/verify_audit.py,sha256=gWhde7gETKSWfBaMm5gEckAO2xmYB_vmgcZ_4FvvyfU,10616
|
41
|
-
pangea_sdk-3.
|
42
|
-
pangea_sdk-3.
|
43
|
-
pangea_sdk-3.
|
41
|
+
pangea_sdk-3.4.0.dist-info/METADATA,sha256=HkC7uL-xyRL0Vlcqoe16pHLZmo2JdNW4z0_iywI9Z3c,6934
|
42
|
+
pangea_sdk-3.4.0.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
43
|
+
pangea_sdk-3.4.0.dist-info/RECORD,,
|
File without changes
|