hippius 0.2.41__py3-none-any.whl → 0.2.42__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.
- {hippius-0.2.41.dist-info → hippius-0.2.42.dist-info}/METADATA +1 -1
- {hippius-0.2.41.dist-info → hippius-0.2.42.dist-info}/RECORD +7 -7
- hippius_sdk/__init__.py +1 -1
- hippius_sdk/client.py +3 -3
- hippius_sdk/ipfs.py +81 -15
- {hippius-0.2.41.dist-info → hippius-0.2.42.dist-info}/WHEEL +0 -0
- {hippius-0.2.41.dist-info → hippius-0.2.42.dist-info}/entry_points.txt +0 -0
@@ -1,10 +1,10 @@
|
|
1
|
-
hippius_sdk/__init__.py,sha256=
|
1
|
+
hippius_sdk/__init__.py,sha256=69XR6atYPkJPYLkUd6NHE15X_4eNNnaKQAy9yIGA4dc,1474
|
2
2
|
hippius_sdk/cli.py,sha256=aqKOYSBSWt7UhcpFt7wf9yIPJ3bznpsJ6ehOnuZ4usI,18235
|
3
3
|
hippius_sdk/cli_assets.py,sha256=rjH3Z5A1CQr2d5CIAAAb0WMCjoZZlMWcdo0f93KqluE,635
|
4
4
|
hippius_sdk/cli_handlers.py,sha256=HkZldE8ZDS6WHu8aSoeS_rYZ4kp3F-Kdzu-weY1c0vU,128258
|
5
5
|
hippius_sdk/cli_parser.py,sha256=z7UvgWvvy04ey-R56qZiCqYc_9RaNq1rVDkQyXoK3JU,21100
|
6
6
|
hippius_sdk/cli_rich.py,sha256=_jTBYMdHi2--fIVwoeNi-EtkdOb6Zy_O2TUiGvU3O7s,7324
|
7
|
-
hippius_sdk/client.py,sha256=
|
7
|
+
hippius_sdk/client.py,sha256=6W50r7-WcMyZNI1j3NOKMpcSMlB819AMKM9w06YqMx0,24302
|
8
8
|
hippius_sdk/config.py,sha256=Hf_aUYzG9ylzqauA_ABUSSB5mBTYbp-VtB36VQt2XDw,21981
|
9
9
|
hippius_sdk/db/README.md,sha256=okDeI1qgkaZqXSlJ8L0xIE4UpuxO-qEGPIbXUvSHQjU,2030
|
10
10
|
hippius_sdk/db/env.db.template,sha256=_6hEC3IvkzCDOAzG1_yJUKRUfCTMciNaJUicZpMCat4,217
|
@@ -13,12 +13,12 @@ hippius_sdk/db/migrations/20241202000001_switch_to_subaccount_encryption.sql,sha
|
|
13
13
|
hippius_sdk/db/setup_database.sh,sha256=STp03qxkp2RmIVr6YZIcvQQm-_LLUOb6Jobh-52HWmg,3115
|
14
14
|
hippius_sdk/db_utils.py,sha256=-x0rbN0as7Tn3PJPZBYCgreZe52FLH40ppA1TLxsg90,1851
|
15
15
|
hippius_sdk/errors.py,sha256=LScJJmawVAx7aRzqqQguYSkf9iazSjEQEBNlD_GXZ6Y,1589
|
16
|
-
hippius_sdk/ipfs.py,sha256=
|
16
|
+
hippius_sdk/ipfs.py,sha256=CpVSEKVrHrZAXrhJsCPPZcADSx2tpE_ktA1TLlMiUQc,103749
|
17
17
|
hippius_sdk/ipfs_core.py,sha256=WG7bGLk-threOvmumizwh1dnd5zqbIkTXy1y-BRGayI,12789
|
18
18
|
hippius_sdk/key_storage.py,sha256=SXFd6aGQw9MDLGX2vSBuAY7rdX-k5EvFm63z7_n-8yQ,8148
|
19
19
|
hippius_sdk/substrate.py,sha256=4a7UIE4UqGcDW7luKTBgSDqfb2OIZusB39G1UiRs_YU,50158
|
20
20
|
hippius_sdk/utils.py,sha256=rJ611yvwKSyiBpYU3w-SuyQxoghMGU-ePuslrPv5H5g,7388
|
21
|
-
hippius-0.2.
|
22
|
-
hippius-0.2.
|
23
|
-
hippius-0.2.
|
24
|
-
hippius-0.2.
|
21
|
+
hippius-0.2.42.dist-info/METADATA,sha256=kSv4QdslPlxwgECpO3_UAq8-CAQGhtK8JEZ-zi7xKgU,30088
|
22
|
+
hippius-0.2.42.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
23
|
+
hippius-0.2.42.dist-info/entry_points.txt,sha256=bFAZjW3vndretf9-8s587jA2ebMVI7puhn_lVs8jPc8,149
|
24
|
+
hippius-0.2.42.dist-info/RECORD,,
|
hippius_sdk/__init__.py
CHANGED
@@ -26,7 +26,7 @@ from hippius_sdk.config import (
|
|
26
26
|
from hippius_sdk.ipfs import IPFSClient, S3PublishResult, S3DownloadResult
|
27
27
|
from hippius_sdk.utils import format_cid, format_size, hex_to_ipfs_cid
|
28
28
|
|
29
|
-
__version__ = "0.2.
|
29
|
+
__version__ = "0.2.42"
|
30
30
|
__all__ = [
|
31
31
|
"HippiusClient",
|
32
32
|
"IPFSClient",
|
hippius_sdk/client.py
CHANGED
@@ -600,12 +600,12 @@ class HippiusClient:
|
|
600
600
|
auto_decrypt: Whether to attempt automatic decryption (default: True)
|
601
601
|
download_node: IPFS node URL for download (default: local node)
|
602
602
|
return_bytes: If True, return bytes instead of saving to file
|
603
|
-
streaming: If True, return raw streaming iterator
|
603
|
+
streaming: If True, return decrypted bytes when auto_decrypt=True, or raw streaming iterator when auto_decrypt=False
|
604
604
|
|
605
605
|
Returns:
|
606
606
|
S3DownloadResult: Download info and decryption status (default)
|
607
|
-
bytes: Raw decrypted content when return_bytes=True
|
608
|
-
AsyncIterator[bytes]: Raw streaming iterator when streaming=True
|
607
|
+
bytes: Raw decrypted content when return_bytes=True or streaming=True with auto_decrypt=True
|
608
|
+
AsyncIterator[bytes]: Raw streaming iterator when streaming=True and auto_decrypt=False
|
609
609
|
|
610
610
|
Raises:
|
611
611
|
HippiusIPFSError: If IPFS download fails
|
hippius_sdk/ipfs.py
CHANGED
@@ -69,6 +69,7 @@ class S3PublishPin(BaseModel):
|
|
69
69
|
cid: str
|
70
70
|
subaccount: str
|
71
71
|
file_path: str
|
72
|
+
file_name: str
|
72
73
|
pin_node: str
|
73
74
|
substrate_url: str
|
74
75
|
|
@@ -2181,6 +2182,7 @@ class IPFSClient:
|
|
2181
2182
|
cid=cid,
|
2182
2183
|
subaccount=subaccount_id,
|
2183
2184
|
file_path=filename,
|
2185
|
+
file_name=filename,
|
2184
2186
|
pin_node=pin_node,
|
2185
2187
|
substrate_url=substrate_url,
|
2186
2188
|
)
|
@@ -2202,7 +2204,7 @@ class IPFSClient:
|
|
2202
2204
|
This method provides multiple output modes:
|
2203
2205
|
1. File output: Downloads to specified path (default mode)
|
2204
2206
|
2. Bytes output: Returns decrypted bytes in memory (return_bytes=True)
|
2205
|
-
3. Streaming output: Returns raw
|
2207
|
+
3. Streaming output: Returns decrypted bytes or raw iterator based on auto_decrypt (streaming=True)
|
2206
2208
|
|
2207
2209
|
Args:
|
2208
2210
|
cid: Content Identifier (CID) of the file to download
|
@@ -2212,12 +2214,12 @@ class IPFSClient:
|
|
2212
2214
|
auto_decrypt: Whether to attempt automatic decryption (default: True)
|
2213
2215
|
download_node: IPFS node URL for download (default: local node)
|
2214
2216
|
return_bytes: If True, return bytes instead of saving to file
|
2215
|
-
streaming: If True, return raw streaming iterator
|
2217
|
+
streaming: If True, return decrypted bytes when auto_decrypt=True, or raw streaming iterator when auto_decrypt=False
|
2216
2218
|
|
2217
2219
|
Returns:
|
2218
2220
|
S3DownloadResult: Download info and decryption status (default)
|
2219
|
-
bytes: Raw decrypted content when return_bytes=True
|
2220
|
-
AsyncIterator[bytes]: Raw streaming iterator when streaming=True
|
2221
|
+
bytes: Raw decrypted content when return_bytes=True or streaming=True with auto_decrypt=True
|
2222
|
+
AsyncIterator[bytes]: Raw streaming iterator when streaming=True and auto_decrypt=False
|
2221
2223
|
|
2222
2224
|
Raises:
|
2223
2225
|
HippiusIPFSError: If IPFS download fails
|
@@ -2228,18 +2230,80 @@ class IPFSClient:
|
|
2228
2230
|
if streaming and return_bytes:
|
2229
2231
|
raise ValueError("Cannot specify both streaming and return_bytes")
|
2230
2232
|
|
2231
|
-
if streaming and (auto_decrypt or subaccount_id or bucket_name):
|
2232
|
-
logger.warning(
|
2233
|
-
"streaming=True ignores decryption parameters - returns raw encrypted stream"
|
2234
|
-
)
|
2235
|
-
|
2236
2233
|
if streaming:
|
2237
|
-
#
|
2238
|
-
|
2239
|
-
|
2234
|
+
# Validate required parameters for decryption if auto_decrypt is True
|
2235
|
+
if auto_decrypt and (not subaccount_id or not bucket_name):
|
2236
|
+
raise ValueError(
|
2237
|
+
"subaccount_id and bucket_name are required for streaming decryption"
|
2238
|
+
)
|
2239
|
+
|
2240
|
+
if auto_decrypt:
|
2241
|
+
# Return decrypted bytes directly (not streaming)
|
2242
|
+
try:
|
2243
|
+
key_storage_available = is_key_storage_enabled()
|
2244
|
+
except ImportError:
|
2245
|
+
key_storage_available = False
|
2246
|
+
|
2247
|
+
encryption_key_bytes = None
|
2248
|
+
|
2249
|
+
if key_storage_available:
|
2250
|
+
# Create combined key identifier from account+bucket
|
2251
|
+
account_bucket_key = f"{subaccount_id}:{bucket_name}"
|
2252
|
+
|
2253
|
+
try:
|
2254
|
+
existing_key_b64 = await get_key_for_subaccount(
|
2255
|
+
account_bucket_key
|
2256
|
+
)
|
2257
|
+
if existing_key_b64:
|
2258
|
+
encryption_key_bytes = base64.b64decode(existing_key_b64)
|
2259
|
+
except Exception as e:
|
2260
|
+
logger.debug(f"Failed to get encryption key: {e}")
|
2261
|
+
|
2262
|
+
# If key storage decryption failed or wasn't available, try client encryption key
|
2263
|
+
if not encryption_key_bytes and self.encryption_available:
|
2264
|
+
logger.debug("Using client encryption key for streaming decryption")
|
2265
|
+
encryption_key_bytes = self.encryption_key
|
2266
|
+
|
2267
|
+
if not encryption_key_bytes:
|
2268
|
+
logger.warning(
|
2269
|
+
"No encryption key found - downloading raw encrypted data as bytes"
|
2270
|
+
)
|
2271
|
+
# Return raw encrypted data as bytes
|
2272
|
+
encrypted_data = b""
|
2273
|
+
async for chunk in self._get_ipfs_stream(cid, download_node):
|
2274
|
+
encrypted_data += chunk
|
2275
|
+
return encrypted_data
|
2276
|
+
|
2277
|
+
# Stream and decrypt the content using hybrid buffered approach
|
2278
|
+
import nacl.secret
|
2279
|
+
|
2280
|
+
# Collect all encrypted data first
|
2281
|
+
logger.debug("Buffering encrypted content for decryption")
|
2282
|
+
encrypted_data = b""
|
2240
2283
|
async for chunk in self._get_ipfs_stream(cid, download_node):
|
2241
|
-
|
2242
|
-
|
2284
|
+
encrypted_data += chunk
|
2285
|
+
|
2286
|
+
# Decrypt the complete buffered content and return as bytes
|
2287
|
+
try:
|
2288
|
+
box = nacl.secret.SecretBox(encryption_key_bytes)
|
2289
|
+
decrypted_data = box.decrypt(encrypted_data)
|
2290
|
+
logger.info(f"Successfully decrypted {len(decrypted_data)} bytes")
|
2291
|
+
|
2292
|
+
# Return all decrypted data as bytes
|
2293
|
+
return decrypted_data
|
2294
|
+
|
2295
|
+
except Exception as decrypt_error:
|
2296
|
+
logger.error(f"Streaming decryption failed: {decrypt_error}")
|
2297
|
+
raise ValueError(
|
2298
|
+
f"Failed to decrypt streaming content: {decrypt_error}"
|
2299
|
+
)
|
2300
|
+
else:
|
2301
|
+
# Return raw streaming iterator from IPFS node - no processing
|
2302
|
+
async def streaming_wrapper():
|
2303
|
+
async for chunk in self._get_ipfs_stream(cid, download_node):
|
2304
|
+
yield chunk
|
2305
|
+
|
2306
|
+
return streaming_wrapper()
|
2243
2307
|
|
2244
2308
|
start_time = time.time()
|
2245
2309
|
|
@@ -2256,7 +2320,9 @@ class IPFSClient:
|
|
2256
2320
|
try:
|
2257
2321
|
# Create parent directories if they don't exist (only for file output mode)
|
2258
2322
|
if not return_bytes:
|
2259
|
-
os.makedirs(
|
2323
|
+
os.makedirs(
|
2324
|
+
os.path.dirname(os.path.abspath(output_path)), exist_ok=True
|
2325
|
+
)
|
2260
2326
|
|
2261
2327
|
download_client = AsyncIPFSClient(api_url=download_node)
|
2262
2328
|
|
File without changes
|
File without changes
|