hippius 0.2.41__py3-none-any.whl → 0.2.43__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.43.dist-info}/METADATA +1 -1
- {hippius-0.2.41.dist-info → hippius-0.2.43.dist-info}/RECORD +7 -7
- hippius_sdk/__init__.py +1 -1
- hippius_sdk/client.py +3 -3
- hippius_sdk/ipfs.py +86 -18
- {hippius-0.2.41.dist-info → hippius-0.2.43.dist-info}/WHEEL +0 -0
- {hippius-0.2.41.dist-info → hippius-0.2.43.dist-info}/entry_points.txt +0 -0
@@ -1,10 +1,10 @@
|
|
1
|
-
hippius_sdk/__init__.py,sha256=
|
1
|
+
hippius_sdk/__init__.py,sha256=Bd28xE63utmKDUUrc5Cf72bEqcF7jjsCCvyQ2Nu_61A,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=los32BjKuVMX9v4GWT-mXUQuxAm2Quc8GjKOMqH42LU,103808
|
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.43.dist-info/METADATA,sha256=PLLDKu0azfbHrOr6Ay_XUB0neKsKs6ujiwgUBlC5Ja0,30088
|
22
|
+
hippius-0.2.43.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
23
|
+
hippius-0.2.43.dist-info/entry_points.txt,sha256=bFAZjW3vndretf9-8s587jA2ebMVI7puhn_lVs8jPc8,149
|
24
|
+
hippius-0.2.43.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.43"
|
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
|
|
@@ -2113,7 +2114,7 @@ class IPFSClient:
|
|
2113
2114
|
except Exception as e:
|
2114
2115
|
raise HippiusIPFSError(
|
2115
2116
|
f"Failed to upload content to store node {store_node}: {str(e)}"
|
2116
|
-
)
|
2117
|
+
) from e
|
2117
2118
|
|
2118
2119
|
# Step 2: Pin to pin_node (remote) for persistence and backup
|
2119
2120
|
try:
|
@@ -2123,7 +2124,7 @@ class IPFSClient:
|
|
2123
2124
|
except Exception as e:
|
2124
2125
|
raise HippiusIPFSError(
|
2125
2126
|
f"Failed to pin content to pin node {pin_node}: {str(e)}"
|
2126
|
-
)
|
2127
|
+
) from e
|
2127
2128
|
|
2128
2129
|
# Conditionally publish to substrate marketplace based on publish flag
|
2129
2130
|
if publish:
|
@@ -2166,7 +2167,9 @@ class IPFSClient:
|
|
2166
2167
|
logger.debug(
|
2167
2168
|
"Possible causes: insufficient credits, network issues, invalid seed phrase, or substrate node unavailability"
|
2168
2169
|
)
|
2169
|
-
raise HippiusSubstrateError(
|
2170
|
+
raise HippiusSubstrateError(
|
2171
|
+
f"Failed to publish to substrate: {str(e)}"
|
2172
|
+
) from e
|
2170
2173
|
|
2171
2174
|
return S3PublishResult(
|
2172
2175
|
cid=cid,
|
@@ -2181,6 +2184,7 @@ class IPFSClient:
|
|
2181
2184
|
cid=cid,
|
2182
2185
|
subaccount=subaccount_id,
|
2183
2186
|
file_path=filename,
|
2187
|
+
file_name=filename,
|
2184
2188
|
pin_node=pin_node,
|
2185
2189
|
substrate_url=substrate_url,
|
2186
2190
|
)
|
@@ -2202,7 +2206,7 @@ class IPFSClient:
|
|
2202
2206
|
This method provides multiple output modes:
|
2203
2207
|
1. File output: Downloads to specified path (default mode)
|
2204
2208
|
2. Bytes output: Returns decrypted bytes in memory (return_bytes=True)
|
2205
|
-
3. Streaming output: Returns raw
|
2209
|
+
3. Streaming output: Returns decrypted bytes or raw iterator based on auto_decrypt (streaming=True)
|
2206
2210
|
|
2207
2211
|
Args:
|
2208
2212
|
cid: Content Identifier (CID) of the file to download
|
@@ -2212,12 +2216,12 @@ class IPFSClient:
|
|
2212
2216
|
auto_decrypt: Whether to attempt automatic decryption (default: True)
|
2213
2217
|
download_node: IPFS node URL for download (default: local node)
|
2214
2218
|
return_bytes: If True, return bytes instead of saving to file
|
2215
|
-
streaming: If True, return raw streaming iterator
|
2219
|
+
streaming: If True, return decrypted bytes when auto_decrypt=True, or raw streaming iterator when auto_decrypt=False
|
2216
2220
|
|
2217
2221
|
Returns:
|
2218
2222
|
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
|
2223
|
+
bytes: Raw decrypted content when return_bytes=True or streaming=True with auto_decrypt=True
|
2224
|
+
AsyncIterator[bytes]: Raw streaming iterator when streaming=True and auto_decrypt=False
|
2221
2225
|
|
2222
2226
|
Raises:
|
2223
2227
|
HippiusIPFSError: If IPFS download fails
|
@@ -2228,18 +2232,80 @@ class IPFSClient:
|
|
2228
2232
|
if streaming and return_bytes:
|
2229
2233
|
raise ValueError("Cannot specify both streaming and return_bytes")
|
2230
2234
|
|
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
2235
|
if streaming:
|
2237
|
-
#
|
2238
|
-
|
2239
|
-
|
2236
|
+
# Validate required parameters for decryption if auto_decrypt is True
|
2237
|
+
if auto_decrypt and (not subaccount_id or not bucket_name):
|
2238
|
+
raise ValueError(
|
2239
|
+
"subaccount_id and bucket_name are required for streaming decryption"
|
2240
|
+
)
|
2241
|
+
|
2242
|
+
if auto_decrypt:
|
2243
|
+
# Return decrypted bytes directly (not streaming)
|
2244
|
+
try:
|
2245
|
+
key_storage_available = is_key_storage_enabled()
|
2246
|
+
except ImportError:
|
2247
|
+
key_storage_available = False
|
2248
|
+
|
2249
|
+
encryption_key_bytes = None
|
2250
|
+
|
2251
|
+
if key_storage_available:
|
2252
|
+
# Create combined key identifier from account+bucket
|
2253
|
+
account_bucket_key = f"{subaccount_id}:{bucket_name}"
|
2254
|
+
|
2255
|
+
try:
|
2256
|
+
existing_key_b64 = await get_key_for_subaccount(
|
2257
|
+
account_bucket_key
|
2258
|
+
)
|
2259
|
+
if existing_key_b64:
|
2260
|
+
encryption_key_bytes = base64.b64decode(existing_key_b64)
|
2261
|
+
except Exception as e:
|
2262
|
+
logger.debug(f"Failed to get encryption key: {e}")
|
2263
|
+
|
2264
|
+
# If key storage decryption failed or wasn't available, try client encryption key
|
2265
|
+
if not encryption_key_bytes and self.encryption_available:
|
2266
|
+
logger.debug("Using client encryption key for streaming decryption")
|
2267
|
+
encryption_key_bytes = self.encryption_key
|
2268
|
+
|
2269
|
+
if not encryption_key_bytes:
|
2270
|
+
logger.warning(
|
2271
|
+
"No encryption key found - downloading raw encrypted data as bytes"
|
2272
|
+
)
|
2273
|
+
# Return raw encrypted data as bytes
|
2274
|
+
encrypted_data = b""
|
2275
|
+
async for chunk in self._get_ipfs_stream(cid, download_node):
|
2276
|
+
encrypted_data += chunk
|
2277
|
+
return encrypted_data
|
2278
|
+
|
2279
|
+
# Stream and decrypt the content using hybrid buffered approach
|
2280
|
+
import nacl.secret
|
2281
|
+
|
2282
|
+
# Collect all encrypted data first
|
2283
|
+
logger.debug("Buffering encrypted content for decryption")
|
2284
|
+
encrypted_data = b""
|
2240
2285
|
async for chunk in self._get_ipfs_stream(cid, download_node):
|
2241
|
-
|
2242
|
-
|
2286
|
+
encrypted_data += chunk
|
2287
|
+
|
2288
|
+
# Decrypt the complete buffered content and return as bytes
|
2289
|
+
try:
|
2290
|
+
box = nacl.secret.SecretBox(encryption_key_bytes)
|
2291
|
+
decrypted_data = box.decrypt(encrypted_data)
|
2292
|
+
logger.info(f"Successfully decrypted {len(decrypted_data)} bytes")
|
2293
|
+
|
2294
|
+
# Return all decrypted data as bytes
|
2295
|
+
return decrypted_data
|
2296
|
+
|
2297
|
+
except Exception as decrypt_error:
|
2298
|
+
logger.error(f"Streaming decryption failed: {decrypt_error}")
|
2299
|
+
raise ValueError(
|
2300
|
+
f"Failed to decrypt streaming content: {decrypt_error}"
|
2301
|
+
)
|
2302
|
+
else:
|
2303
|
+
# Return raw streaming iterator from IPFS node - no processing
|
2304
|
+
async def streaming_wrapper():
|
2305
|
+
async for chunk in self._get_ipfs_stream(cid, download_node):
|
2306
|
+
yield chunk
|
2307
|
+
|
2308
|
+
return streaming_wrapper()
|
2243
2309
|
|
2244
2310
|
start_time = time.time()
|
2245
2311
|
|
@@ -2256,7 +2322,9 @@ class IPFSClient:
|
|
2256
2322
|
try:
|
2257
2323
|
# Create parent directories if they don't exist (only for file output mode)
|
2258
2324
|
if not return_bytes:
|
2259
|
-
os.makedirs(
|
2325
|
+
os.makedirs(
|
2326
|
+
os.path.dirname(os.path.abspath(output_path)), exist_ok=True
|
2327
|
+
)
|
2260
2328
|
|
2261
2329
|
download_client = AsyncIPFSClient(api_url=download_node)
|
2262
2330
|
|
File without changes
|
File without changes
|