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/tools.py CHANGED
@@ -95,7 +95,7 @@ def file_events(root_hashes: Dict[int, str], f: io.TextIOWrapper) -> Iterator[Ev
95
95
  else:
96
96
  raise ValueError("invalid data")
97
97
  except (json.JSONDecodeError, ValueError, KeyError) as e:
98
- exit_with_error(f"failed to parse line {idx}: {str(e)}")
98
+ exit_with_error(f"failed to parse line {idx}: {e!s}")
99
99
 
100
100
 
101
101
  def init_audit(token: str, domain: str) -> Audit:
@@ -108,15 +108,14 @@ def init_audit(token: str, domain: str) -> Audit:
108
108
  def make_aware_datetime(d: datetime) -> datetime:
109
109
  if d.tzinfo is None or d.tzinfo.utcoffset(d) is None:
110
110
  return d.replace(tzinfo=timezone.utc)
111
- else:
112
- return d
111
+ return d
113
112
 
114
113
 
115
114
  def filter_deep_none(data: Dict) -> Dict:
116
115
  return {k: v if not isinstance(v, Dict) else filter_deep_none(v) for k, v in data.items() if v is not None}
117
116
 
118
117
 
119
- def _load_env_var(env_var_name: str):
118
+ def _load_env_var(env_var_name: str) -> str:
120
119
  value = os.getenv(env_var_name)
121
120
  if not value:
122
121
  raise PangeaException(f"{env_var_name} env var need to be set")
@@ -124,12 +123,12 @@ def _load_env_var(env_var_name: str):
124
123
  return value
125
124
 
126
125
 
127
- def get_test_domain(environment: TestEnvironment):
126
+ def get_test_domain(environment: TestEnvironment) -> str:
128
127
  env_var_name = f"PANGEA_INTEGRATION_DOMAIN_{environment}"
129
128
  return _load_env_var(env_var_name)
130
129
 
131
130
 
132
- def get_test_token(environment: TestEnvironment):
131
+ def get_test_token(environment: TestEnvironment) -> str:
133
132
  env_var_name = f"PANGEA_INTEGRATION_TOKEN_{environment}"
134
133
  return _load_env_var(env_var_name)
135
134
 
@@ -200,7 +199,7 @@ loggers: Dict[str, bool] = {}
200
199
 
201
200
 
202
201
  def logger_set_pangea_config(logger_name: str, level=logging.DEBUG):
203
- if loggers.get(logger_name, None) is not None:
202
+ if loggers.get(logger_name) is not None:
204
203
  return
205
204
 
206
205
  loggers[logger_name] = True
pangea/utils.py CHANGED
@@ -1,11 +1,14 @@
1
+ from __future__ import annotations
2
+
1
3
  import base64
2
4
  import copy
3
5
  import datetime
4
6
  import io
5
7
  import json
6
- from hashlib import new, sha1, sha256, sha512
8
+ from hashlib import md5, new, sha1, sha256, sha512
9
+ from typing import Union
7
10
 
8
- from google_crc32c import Checksum as CRC32C # type: ignore[import-untyped]
11
+ from google_crc32c import Checksum as CRC32C
9
12
  from pydantic import BaseModel
10
13
 
11
14
 
@@ -64,33 +67,97 @@ def canonicalize(data: dict) -> str:
64
67
  return str(data)
65
68
 
66
69
 
67
- def hash_sha256(data: str) -> str:
68
- # Return sha256 hash in hex format
69
- return sha256(data.encode("ascii")).hexdigest()
70
+ def hash_sha256(input: Union[str, io.BufferedReader]) -> str:
71
+ # Return SHA256 hash in hex format
72
+ hash = sha256()
73
+ if isinstance(input, io.BufferedReader):
74
+ input.seek(0) # restart reading
75
+ while True:
76
+ chunk = input.read(1024 * 1024)
77
+ if not chunk:
78
+ break
79
+ hash.update(chunk)
70
80
 
81
+ input.seek(0) # restart reading
82
+ else:
83
+ hash.update(input) # type: ignore
84
+
85
+ return hash.hexdigest()
71
86
 
72
- def hash_256_filepath(filepath: str) -> str:
73
- data = open(filepath, "rb")
74
- hash = sha256(data.read()).hexdigest()
75
- data.close()
76
- return hash
77
87
 
88
+ def hash_sha1(input: Union[str, io.BufferedReader]) -> str:
89
+ # Return SHA1 hash in hex format
90
+ hash = sha1()
91
+ if isinstance(input, io.BufferedReader):
92
+ input.seek(0) # restart reading
93
+ while True:
94
+ chunk = input.read(1024 * 1024)
95
+ if not chunk:
96
+ break
97
+ hash.update(chunk)
78
98
 
79
- def hash_sha1(data: str) -> str:
80
- # Return sha1 hash in hex format
81
- return sha1(data.encode("ascii")).hexdigest()
99
+ input.seek(0) # restart reading
100
+ else:
101
+ hash.update(input) # type: ignore
102
+
103
+ return hash.hexdigest()
104
+
105
+
106
+ def hash_sha512(input: Union[str, io.BufferedReader]) -> str:
107
+ # Return SHA512 hash in hex format
108
+ hash = sha512()
109
+ if isinstance(input, io.BufferedReader):
110
+ input.seek(0) # restart reading
111
+ while True:
112
+ chunk = input.read(1024 * 1024)
113
+ if not chunk:
114
+ break
115
+ hash.update(chunk)
82
116
 
117
+ input.seek(0) # restart reading
118
+ else:
119
+ hash.update(input) # type: ignore
83
120
 
84
- def hash_sha512(data: str) -> str:
85
- # Return sha512 hash in hex format
86
- return sha512(data.encode("ascii")).hexdigest()
121
+ return hash.hexdigest()
87
122
 
88
123
 
89
- def hash_ntlm(data: str):
90
- # Calculate the NTLM hash
124
+ def hash_ntlm(data: str) -> str:
125
+ # Return NTLM hash in hex format
91
126
  return new("md4", data.encode("utf-16le")).hexdigest()
92
127
 
93
128
 
129
+ def hash_md5(input: Union[str, io.BufferedReader]) -> str:
130
+ # Return MD5 hash in hex format
131
+ hash = md5()
132
+ if isinstance(input, io.BufferedReader):
133
+ input.seek(0) # restart reading
134
+
135
+ while True:
136
+ chunk = input.read(1024 * 1024)
137
+ if not chunk:
138
+ break
139
+ hash.update(chunk)
140
+
141
+ input.seek(0) # restart reading
142
+ else:
143
+ hash.update(input) # type: ignore
144
+
145
+ return hash.hexdigest()
146
+
147
+
148
+ def get_crc32c(data: str) -> str:
149
+ crc = CRC32C()
150
+ crc.update(data)
151
+ return crc.hexdigest().decode("utf-8")
152
+
153
+
154
+ def hash_256_filepath(filepath: str) -> str:
155
+ data = open(filepath, "rb")
156
+ hash = sha256(data.read()).hexdigest()
157
+ data.close()
158
+ return hash
159
+
160
+
94
161
  def get_prefix(hash: str, len: int = 5):
95
162
  return hash[0:len]
96
163
 
@@ -120,3 +187,10 @@ def get_file_upload_params(file: io.BufferedReader) -> FileUploadParams:
120
187
 
121
188
  file.seek(0) # restart reading
122
189
  return FileUploadParams(crc_hex=crc.hexdigest().decode("utf-8"), sha256_hex=sha.hexdigest(), size=size)
190
+
191
+
192
+ def get_file_size(file: io.BufferedReader) -> int:
193
+ file.seek(0, io.SEEK_END)
194
+ size = file.tell()
195
+ file.seek(0) # restart reading
196
+ return size
pangea/verify_audit.py CHANGED
@@ -211,7 +211,7 @@ def _fetch_roots(tree_name: str, tree_size: int, leaf_index: Optional[int]) -> S
211
211
  # try Arweave first
212
212
  try:
213
213
  logger.debug(f"Fetching root(s) {comma_sep(pending_roots)} from Arweave")
214
- arweave_roots |= {int(k): v for k, v in get_arweave_published_roots(tree_name, pending_roots).items()} # type: ignore[operator]
214
+ arweave_roots |= {int(k): v for k, v in get_arweave_published_roots(tree_name, pending_roots).items()}
215
215
  update_pending_roots()
216
216
  except:
217
217
  pass
@@ -224,7 +224,7 @@ def _fetch_roots(tree_name: str, tree_size: int, leaf_index: Optional[int]) -> S
224
224
  # and then Pangea (if we've set an audit client)
225
225
  try:
226
226
  logger.debug(f"Fetching root(s) {comma_sep(pending_roots)} from Pangea")
227
- pangea_roots |= {int(k): v for k, v in get_pangea_roots(tree_name, pending_roots).items()} # type: ignore[operator]
227
+ pangea_roots |= {int(k): v for k, v in get_pangea_roots(tree_name, pending_roots).items()}
228
228
  update_pending_roots()
229
229
  status = Status.SUCCEEDED_PANGEA
230
230
  except:
@@ -244,7 +244,7 @@ def _fetch_roots(tree_name: str, tree_size: int, leaf_index: Optional[int]) -> S
244
244
 
245
245
 
246
246
  def _verify_membership_proof(tree_size: int, node_hash: str, proof: Optional[str]) -> Status:
247
- pub_roots: Dict[int, Union[Root, PublishedRoot]] = arweave_roots | pangea_roots # type: ignore[operator]
247
+ pub_roots: Dict[int, Union[Root, PublishedRoot]] = arweave_roots | pangea_roots
248
248
 
249
249
  log_section("Checking membership proof")
250
250
 
@@ -311,7 +311,7 @@ def _fix_consistency_proof(pub_roots: Dict[int, Union[Root, PublishedRoot]], tre
311
311
 
312
312
 
313
313
  def _verify_consistency_proof(tree_name: str, leaf_index: Optional[int]) -> Status:
314
- pub_roots: Dict[int, Union[Root, PublishedRoot]] = arweave_roots | pangea_roots # type: ignore[operator]
314
+ pub_roots: Dict[int, Union[Root, PublishedRoot]] = arweave_roots | pangea_roots
315
315
 
316
316
  log_section("Checking consistency proof")
317
317
 
@@ -1,16 +1,15 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pangea-sdk
3
- Version: 4.4.0
3
+ Version: 5.1.0
4
4
  Summary: Pangea API SDK
5
5
  Home-page: https://pangea.cloud/docs/sdk/python/
6
6
  License: MIT
7
7
  Keywords: Pangea,SDK,Audit
8
8
  Author: Glenn Gallien
9
9
  Author-email: glenn.gallien@pangea.cloud
10
- Requires-Python: >=3.8.0,<4.0.0
10
+ Requires-Python: >=3.9.0,<4.0.0
11
11
  Classifier: License :: OSI Approved :: MIT License
12
12
  Classifier: Programming Language :: Python :: 3
13
- Classifier: Programming Language :: Python :: 3.8
14
13
  Classifier: Programming Language :: Python :: 3.9
15
14
  Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
@@ -41,7 +40,7 @@ Description-Content-Type: text/markdown
41
40
 
42
41
  # Pangea Python SDK
43
42
 
44
- A Python SDK for integrating with Pangea services. Supports Python v3.8 and
43
+ A Python SDK for integrating with Pangea services. Supports Python v3.9 and
45
44
  above.
46
45
 
47
46
  ## Installation
@@ -1,8 +1,8 @@
1
- pangea/__init__.py,sha256=v6ZDmf842vyF60xDR-QFmFgqOrACNjTFpxIBQcx3gFc,246
1
+ pangea/__init__.py,sha256=ie7DdC7-YE5szWaPCHAlk2umsSOUBPoE_0HSaSazcqE,246
2
2
  pangea/asyncio/__init__.py,sha256=kjEMkqMQ521LlMSu5jn3_WgweyArwVZ2C-s3x7mR6Pk,45
3
3
  pangea/asyncio/file_uploader.py,sha256=wI7epib7Rc5jtZw4eJ1L1SlmutDG6CPv59C8N2UPhtY,1436
4
- pangea/asyncio/request.py,sha256=KMfQYC027EBeyYyMlvnDtjxbpaRj9xubeqAdpot3F3U,17168
5
- pangea/asyncio/services/__init__.py,sha256=hMeTMnksGimg-fS_XMpRgh02a7BNcLYCt56tnChYeC4,356
4
+ pangea/asyncio/request.py,sha256=b9GNZl-gOk-NhJtOU0Ds7RCF88c_mHpNo0H-3H-hK9I,17478
5
+ pangea/asyncio/services/__init__.py,sha256=3IkiTqY_RtFndI7aoDTrb1yLv8xos_cKhmGS1TULcmw,386
6
6
  pangea/asyncio/services/audit.py,sha256=bZ7gdkVWkzqLqUVc1Wnf3oDAaCLg97-zTWhY8UdX0_Y,26549
7
7
  pangea/asyncio/services/authn.py,sha256=rPeLJweL8mYH_t4ebcQn4n_Wglr3kClKNnCXNCimZU4,46622
8
8
  pangea/asyncio/services/authz.py,sha256=HgW9R8DeW19wS7fpgq0NWOx41wZWcn6NYS4NMbi8p1A,9482
@@ -12,23 +12,24 @@ pangea/asyncio/services/file_scan.py,sha256=PLG1O-PL4Yk9uY9D6NbMrZ5LHg70Z311s7bF
12
12
  pangea/asyncio/services/intel.py,sha256=cCm3VwWxUzEUCNhuPCeejJvr4uOeLXuYDbDwTzNG6Aw,38121
13
13
  pangea/asyncio/services/redact.py,sha256=jRNtXr_DZ_cY7guhut-eZmOEhy2uN_VCXrjGH6bkh74,7265
14
14
  pangea/asyncio/services/sanitize.py,sha256=bf98J-s-P51oSKqNBgR0wj5mlHOCBwpjWz7k0NdXCKQ,7899
15
- pangea/asyncio/services/vault.py,sha256=gFch7dVFZzjcTryn68AR4Xbj37U4A_LxfCMrX2mhtSk,53271
15
+ pangea/asyncio/services/share.py,sha256=UYJeUKA3NLSFA8R0X7B6yBi2U1g4q04O4ftrp9SMCzA,26097
16
+ pangea/asyncio/services/vault.py,sha256=VqrJGSEdq6MlZRI6cJpkthhIsqLClSQdgVxwYCbIwEk,77079
16
17
  pangea/audit_logger.py,sha256=gRkCfUUT5LDNaycwxkhZUySgY47jDfn1ZeKOul4XCQI,3842
17
18
  pangea/config.py,sha256=mQUu8GX_6weIuv3vjNdG5plppXskXYASmxMWtFQh-hc,1662
18
- pangea/crypto/rsa.py,sha256=EZ3IBkycqXiEkeurK7GZXgf498hJFU3Yp-ggA5oGu9I,1696
19
+ pangea/crypto/rsa.py,sha256=mwSiNy571KAGr3F6oEM0CXWkl9D023ch8ldbZZeLj_4,4747
19
20
  pangea/deep_verify.py,sha256=mocaGbC6XLbMTVWxTpMv4oJtXGPWpT-SbFqT3obpiZs,8443
20
21
  pangea/deprecated.py,sha256=IjFYEVvY1E0ld0SMkEYC1o62MAleX3nnT1If2dFVbHo,608
21
22
  pangea/dump_audit.py,sha256=1Je8D2fXwU4PWcZ-ZD4icfO3DNFvWqJkwsac4qFEhOo,7025
22
23
  pangea/exceptions.py,sha256=OBtzUECpNa6vNp8ySkHC-tm4QjFRCOAHBkMHqzAlOu8,5656
23
24
  pangea/file_uploader.py,sha256=4RQ44xt-faApC61nn2PlwHT7XYrJ4GeQA8Ug4tySEAg,1227
24
25
  pangea/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- pangea/request.py,sha256=fKMuf2tuAguK2TnSSMpmdcBdHlgsYFQoYCBVh3mUkBY,24259
26
- pangea/response.py,sha256=rjQuTAHLSAB0m2uAsdbt11xUVL5cCGT4uTRzQhUz9hE,7321
27
- pangea/services/__init__.py,sha256=YPXqGGUlAm2oHQNArhDVfr6Y1Gq2o4nhwx_dpdKe74c,309
26
+ pangea/request.py,sha256=-XC1azZtymldOAQLbrSRzNX-h0B_lK-bQcinXyK0QKs,24410
27
+ pangea/response.py,sha256=lPAcYsF9Xg166CiyhCofVmQA-W4jevh0MQXxUa8Re68,7737
28
+ pangea/services/__init__.py,sha256=-QsZxRzRq_V1x1lmS_mu4310MNm0DkM4r6g6rfVGnOc,340
28
29
  pangea/services/audit/audit.py,sha256=IFv7jANA8S2SypQVS47x94_Cr5Z9zSsL9Dp9eXw9RHk,39593
29
30
  pangea/services/audit/exceptions.py,sha256=bhVuYe4ammacOVxwg98CChxvwZf5FKgR2DcgqILOcwc,471
30
31
  pangea/services/audit/models.py,sha256=1h1B9eSYQMYG3f8WNi1UcDX2-impRrET_ErjJYUnj7M,14678
31
- pangea/services/audit/signing.py,sha256=EYuZN6pcFOjDJBG6S65jesE_8xOz5SNms6qHZ1qambQ,5541
32
+ pangea/services/audit/signing.py,sha256=5A4hvPtpfP2kMz8bsiiKUACriXbh5dv9gb_rbqiUtuI,5583
32
33
  pangea/services/audit/util.py,sha256=Zq1qvfeplYfhCP_ud5YMvntSB0UvnCdsuYbOzZkHbjg,7620
33
34
  pangea/services/authn/authn.py,sha256=cZKl2Ixc6HwHnkRecpSaAGTQUgaZUtxfLa0T3S03HMs,45478
34
35
  pangea/services/authn/models.py,sha256=HH5su6jx3O9AwVGzASXZ99-eIWjgXEP5LhIVdewM13s,22394
@@ -39,14 +40,17 @@ pangea/services/file_scan.py,sha256=QiO80uKqB_BnAOiYQKznXfxpa5j40qqETE3-zBRT_QE,
39
40
  pangea/services/intel.py,sha256=CziBhC5K6O_kBXpD8zgJLpDtLHzBRgATGW4gHHFJT48,52039
40
41
  pangea/services/redact.py,sha256=ZYXkzEoriLJyCqaj5dqmgsC56mIz4T3pPToZ7TcNfhg,11465
41
42
  pangea/services/sanitize.py,sha256=XP5D4CcbCZfzgU567X6H5eFBWwZuYSsHdvsdrQAZekY,12767
42
- pangea/services/vault/models/asymmetric.py,sha256=xr8oZnjzExMYcbzPJRG3xPXSmhumKDKn7RO90RvdrwU,1526
43
- pangea/services/vault/models/common.py,sha256=FOmi2UN5cEgSsrM-aDT1KWLK4TTgrtMukqNczrnWH6w,15491
44
- pangea/services/vault/models/secret.py,sha256=cLgEj-_BeGkB4-pmSeTkWVyasFbaJwcEltIEcOyf1U8,481
45
- pangea/services/vault/models/symmetric.py,sha256=UfsLvGYmQ7phuxK64f1b1z1Z_nQr2NU_wKINlpbkVpQ,1516
46
- pangea/services/vault/vault.py,sha256=pv52dpZM0yicdtNra0Yd4AdkWUZC91Yk4rATthu1bsU,52956
47
- pangea/tools.py,sha256=sa2pSz-L8tB6GcZg6lghsmm8w0qMQAIkzqcv7dilU6Q,6429
48
- pangea/utils.py,sha256=pMSwL8B-owtrjeWYRjxuyaTQN4V-HsCT669KtOLU3Sw,3195
49
- pangea/verify_audit.py,sha256=rvni5akz_P2kYLAGAeA1A5gY6XGpXpAQpbIa7V1PoRY,17458
50
- pangea_sdk-4.4.0.dist-info/METADATA,sha256=Pdac62iEWB9wChXMZrR2saCrBMXnsLuWJlhIx6ovA44,7545
51
- pangea_sdk-4.4.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
52
- pangea_sdk-4.4.0.dist-info/RECORD,,
43
+ pangea/services/share/file_format.py,sha256=1svO1ee_aenA9zoO_AaU-Rk5Ulp7kcPOc_KwNoluyQE,2797
44
+ pangea/services/share/share.py,sha256=iyP32UNWoT2F9C_65FiXWrVoNoO7dBjf0tVX1mF2Fz0,45644
45
+ pangea/services/vault/models/asymmetric.py,sha256=vspijmEvHm5WXri_fjOWfQc4maYyZfhDkLuaTM8-PZo,4991
46
+ pangea/services/vault/models/common.py,sha256=PSZRFqHTUtEMJJGwywEFM2AU3aV8S-sbcoo3LLQ6uTc,17981
47
+ pangea/services/vault/models/keys.py,sha256=duAuTiOby_D7MloRvN4gNj0P-b-jx9sdtplAWFxsShw,2786
48
+ pangea/services/vault/models/secret.py,sha256=ItGdkulM-SEySfcm4a5yGxMvo_omjC7kChv6gdbFnn8,1142
49
+ pangea/services/vault/models/symmetric.py,sha256=t8xCM1wGGKDBpOqTggFueO4-4-2IFmyxqcs7_PDr7U0,2562
50
+ pangea/services/vault/vault.py,sha256=ow-Zm7PYzfWIfUcA4UNnpeL2DHfZM4C7inRDmNR3zQU,76196
51
+ pangea/tools.py,sha256=2-Y4SAHWFv6Ocj42J_bWrVy27M5G3wi7a8LJn0dabHc,6427
52
+ pangea/utils.py,sha256=KNkWK8o9j4iRDLUfAiobL-Hy5fcAxjl0DOFWXAqLK3E,5032
53
+ pangea/verify_audit.py,sha256=nSP17OzoSPdvezRExwfcf45H8ZPZnxZu-CbEp3qFJO0,17354
54
+ pangea_sdk-5.1.0.dist-info/METADATA,sha256=5vdMrWyqNEhM-sU0GbglC7Y8VfLkTVDe5_Z32-TNT8E,7495
55
+ pangea_sdk-5.1.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
56
+ pangea_sdk-5.1.0.dist-info/RECORD,,