hippius 0.2.3__tar.gz → 0.2.4__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hippius
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: Python SDK and CLI for Hippius blockchain storage
5
5
  Home-page: https://github.com/thenervelab/hippius-sdk
6
6
  Author: Dubs
@@ -44,6 +44,7 @@ A Python SDK and CLI for interacting with Hippius blockchain storage, designed s
44
44
  - Substrate blockchain integration for decentralized storage references
45
45
  - End-to-end encryption for secure file storage and retrieval
46
46
  - Built-in CLI tools for encryption key generation
47
+ - Asynchronous API for efficient I/O operations
47
48
 
48
49
  ## Installation
49
50
 
@@ -61,6 +62,7 @@ poetry add hippius -E clipboard
61
62
  ## Quick Start
62
63
 
63
64
  ```python
65
+ import asyncio
64
66
  from hippius_sdk import HippiusClient
65
67
 
66
68
  # Initialize the client with default connections to Hippius network
@@ -72,41 +74,46 @@ client = HippiusClient(
72
74
  ipfs_api_url="https://store.hippius.network", # For uploads (default)
73
75
  )
74
76
 
75
- # Upload a file to IPFS
76
- result = client.upload_file("path/to/your/model.pt")
77
- print(f"File uploaded with CID: {result['cid']}")
78
- print(f"File size: {result['size_formatted']}")
79
-
80
- # Download a file from IPFS
81
- dl_result = client.download_file(result['cid'], "path/to/save/model.pt")
82
- print(f"Download successful in {dl_result['elapsed_seconds']} seconds")
83
- print(f"File size: {dl_result['size_formatted']}")
84
-
85
- # Check if a file exists
86
- exists_result = client.exists(result['cid'])
87
- print(f"File exists: {exists_result['exists']}")
88
- print(f"Gateway URL: {exists_result['gateway_url']}")
89
-
90
- # Get file content directly
91
- content_result = client.cat(result['cid'])
92
- if content_result['is_text']:
93
- print(f"Content preview: {content_result['text_preview']}")
94
- else:
95
- print(f"Binary content (hex): {content_result['hex_preview']}")
96
- print(f"Content size: {content_result['size_formatted']}")
97
-
98
- # Pin a file to ensure it stays on the network
99
- pin_result = client.pin(result['cid'])
100
- print(f"Pinning successful: {pin_result['success']}")
101
- print(f"Message: {pin_result['message']}")
102
-
103
- # Format a CID for display
104
- formatted_cid = client.format_cid(result['cid'])
105
- print(f"Formatted CID: {formatted_cid}")
106
-
107
- # Format file size for display
108
- formatted_size = client.format_size(1024 * 1024)
109
- print(f"Formatted size: {formatted_size}") # Output: 1.00 MB
77
+ async def main():
78
+ # Upload a file to IPFS
79
+ result = await client.upload_file("path/to/your/model.pt")
80
+ print(f"File uploaded with CID: {result['cid']}")
81
+ print(f"File size: {result['size_formatted']}")
82
+
83
+ # Download a file from IPFS
84
+ dl_result = await client.download_file(result['cid'], "path/to/save/model.pt")
85
+ print(f"Download successful in {dl_result['elapsed_seconds']} seconds")
86
+ print(f"File size: {dl_result['size_formatted']}")
87
+
88
+ # Check if a file exists
89
+ exists_result = await client.exists(result['cid'])
90
+ print(f"File exists: {exists_result['exists']}")
91
+ print(f"Gateway URL: {exists_result['gateway_url']}")
92
+
93
+ # Get file content directly
94
+ content_result = await client.cat(result['cid'])
95
+ if content_result['is_text']:
96
+ print(f"Content preview: {content_result['text_preview']}")
97
+ else:
98
+ print(f"Binary content (hex): {content_result['hex_preview']}")
99
+ print(f"Content size: {content_result['size_formatted']}")
100
+
101
+ # Pin a file to ensure it stays on the network
102
+ pin_result = await client.pin(result['cid'])
103
+ print(f"Pinning successful: {pin_result['success']}")
104
+ print(f"Message: {pin_result['message']}")
105
+
106
+ # Format a CID for display (non-async utility function)
107
+ formatted_cid = client.format_cid(result['cid'])
108
+ print(f"Formatted CID: {formatted_cid}")
109
+
110
+ # Format file size for display (non-async utility function)
111
+ formatted_size = client.format_size(1024 * 1024)
112
+ print(f"Formatted size: {formatted_size}") # Output: 1.00 MB
113
+
114
+ # Run the async function
115
+ if __name__ == "__main__":
116
+ asyncio.run(main())
110
117
  ```
111
118
 
112
119
  ## Encryption Support
@@ -137,6 +144,7 @@ The SDK can be configured to use encryption in several ways:
137
144
  2. Directly in code:
138
145
  ```python
139
146
  import base64
147
+ import asyncio
140
148
  from hippius_sdk import HippiusClient
141
149
 
142
150
  # Decode the base64 key
@@ -148,9 +156,13 @@ The SDK can be configured to use encryption in several ways:
148
156
  encryption_key=encryption_key
149
157
  )
150
158
 
151
- # Or generate a new key programmatically
152
- encoded_key = client.generate_encryption_key()
153
- print(f"Generated key: {encoded_key}")
159
+ async def main():
160
+ # Generate a new key programmatically (non-async utility method)
161
+ encoded_key = client.generate_encryption_key()
162
+ print(f"Generated key: {encoded_key}")
163
+
164
+ # Run the async function
165
+ asyncio.run(main())
154
166
  ```
155
167
 
156
168
  ### Using Encryption
@@ -158,22 +170,31 @@ The SDK can be configured to use encryption in several ways:
158
170
  Once configured, encryption works transparently:
159
171
 
160
172
  ```python
161
- # Upload with encryption (uses default setting)
162
- result = client.upload_file("sensitive_data.txt")
163
-
164
- # Explicitly enable/disable encryption for a specific operation
165
- encrypted_result = client.upload_file("sensitive_data.txt", encrypt=True)
166
- unencrypted_result = client.upload_file("public_data.txt", encrypt=False)
167
-
168
- # Download and decrypt automatically
169
- dl_result = client.download_file(encrypted_result['cid'], "decrypted_file.txt")
173
+ import asyncio
174
+ from hippius_sdk import HippiusClient
170
175
 
171
- # Explicitly control decryption
172
- decrypted_result = client.download_file(encrypted_result['cid'], "output.txt", decrypt=True)
173
- raw_result = client.download_file(encrypted_result['cid'], "still_encrypted.txt", decrypt=False)
176
+ client = HippiusClient()
174
177
 
175
- # View encrypted content
176
- content = client.cat(encrypted_result['cid'], decrypt=True)
178
+ async def main():
179
+ # Upload with encryption (uses default setting)
180
+ result = await client.upload_file("sensitive_data.txt")
181
+
182
+ # Explicitly enable/disable encryption for a specific operation
183
+ encrypted_result = await client.upload_file("sensitive_data.txt", encrypt=True)
184
+ unencrypted_result = await client.upload_file("public_data.txt", encrypt=False)
185
+
186
+ # Download and decrypt automatically
187
+ dl_result = await client.download_file(encrypted_result['cid'], "decrypted_file.txt")
188
+
189
+ # Explicitly control decryption
190
+ decrypted_result = await client.download_file(encrypted_result['cid'], "output.txt", decrypt=True)
191
+ raw_result = await client.download_file(encrypted_result['cid'], "still_encrypted.txt", decrypt=False)
192
+
193
+ # View encrypted content
194
+ content = await client.cat(encrypted_result['cid'], decrypt=True)
195
+
196
+ # Run the async function
197
+ asyncio.run(main())
177
198
  ```
178
199
 
179
200
  ## Erasure Coding
@@ -190,37 +211,42 @@ Hippius SDK supports Reed-Solomon erasure coding for reliable and resilient file
190
211
  ### Using Erasure Coding
191
212
 
192
213
  ```python
214
+ import asyncio
193
215
  from hippius_sdk import HippiusClient
194
216
 
195
217
  client = HippiusClient()
196
218
 
197
- # Erasure code a file with default parameters (k=3, m=5)
198
- result = client.erasure_code_file("large_file.mp4")
199
- metadata_cid = result["metadata_cid"]
200
-
201
- # Use custom parameters for more redundancy
202
- result = client.erasure_code_file(
203
- file_path="important_data.zip",
204
- k=4, # Need 4 chunks to reconstruct
205
- m=10, # Create 10 chunks total (6 redundant)
206
- chunk_size=2097152, # 2MB chunks
207
- encrypt=True # Encrypt before splitting
208
- )
209
-
210
- # Store erasure-coded file in Hippius marketplace
211
- result = client.store_erasure_coded_file(
212
- file_path="critical_backup.tar",
213
- k=3,
214
- m=5,
215
- encrypt=True,
216
- miner_ids=["miner1", "miner2", "miner3"]
217
- )
218
-
219
- # Reconstruct a file from its metadata
220
- reconstructed_path = client.reconstruct_from_erasure_code(
221
- metadata_cid=metadata_cid,
222
- output_file="reconstructed_file.mp4"
223
- )
219
+ async def main():
220
+ # Erasure code a file with default parameters (k=3, m=5)
221
+ result = await client.erasure_code_file("large_file.mp4")
222
+ metadata_cid = result["metadata_cid"]
223
+
224
+ # Use custom parameters for more redundancy
225
+ result = await client.erasure_code_file(
226
+ file_path="important_data.zip",
227
+ k=4, # Need 4 chunks to reconstruct
228
+ m=10, # Create 10 chunks total (6 redundant)
229
+ chunk_size=2097152, # 2MB chunks
230
+ encrypt=True # Encrypt before splitting
231
+ )
232
+
233
+ # Store erasure-coded file in Hippius marketplace
234
+ result = await client.store_erasure_coded_file(
235
+ file_path="critical_backup.tar",
236
+ k=3,
237
+ m=5,
238
+ encrypt=True,
239
+ miner_ids=["miner1", "miner2", "miner3"]
240
+ )
241
+
242
+ # Reconstruct a file from its metadata
243
+ reconstructed_path = await client.reconstruct_from_erasure_code(
244
+ metadata_cid=metadata_cid,
245
+ output_file="reconstructed_file.mp4"
246
+ )
247
+
248
+ # Run the async function
249
+ asyncio.run(main())
224
250
  ```
225
251
 
226
252
  ### When to Use Erasure Coding
@@ -535,55 +561,60 @@ HIPPIUS_ENCRYPT_BY_DEFAULT=true|false
535
561
  ### IPFS Operations
536
562
 
537
563
  ```python
564
+ import asyncio
538
565
  from hippius_sdk import IPFSClient
539
566
 
540
- # Initialize the IPFS client (uses Hippius relay node by default)
541
- ipfs_client = IPFSClient()
542
-
543
- # Or specify custom endpoints
544
- ipfs_client = IPFSClient(
545
- gateway="https://get.hippius.network", # For downloads
546
- api_url="http://relay-fr.hippius.network:5001" # For uploads
547
- )
548
-
549
- # Upload a file
550
- result = ipfs_client.upload_file("path/to/your/file.txt")
551
- cid = result["cid"]
552
- size = result["size_formatted"]
553
-
554
- # Upload a directory
555
- dir_result = ipfs_client.upload_directory("path/to/your/directory")
556
- dir_cid = dir_result["cid"]
557
- file_count = dir_result["file_count"]
558
- total_size = dir_result["size_formatted"]
559
-
560
- # Download a file
561
- dl_result = ipfs_client.download_file(cid, "path/to/save/file.txt")
562
- success = dl_result["success"]
563
- elapsed_time = dl_result["elapsed_seconds"]
564
-
565
- # Check if a CID exists
566
- exists_result = ipfs_client.exists(cid)
567
- exists = exists_result["exists"]
568
- gateway_url = exists_result["gateway_url"]
569
-
570
- # Get file content directly
571
- content_result = ipfs_client.cat(cid)
572
- content = content_result["content"]
573
- is_text = content_result["is_text"]
574
- preview = content_result["text_preview"] if is_text else content_result["hex_preview"]
575
-
576
- # Pin a file
577
- pin_result = ipfs_client.pin(cid)
578
- success = pin_result["success"]
579
- message = pin_result["message"]
580
-
581
- # Format a CID
582
- formatted_cid = ipfs_client.format_cid("6261666b7265696134...") # Hex-encoded CID
583
- # Will return a proper formatted CID like "bafkrei..."
584
-
585
- # Format a file size
586
- human_readable = ipfs_client.format_size(1048576) # 1 MB
567
+ async def main():
568
+ # Initialize the IPFS client (uses Hippius relay node by default)
569
+ ipfs_client = IPFSClient()
570
+
571
+ # Or specify custom endpoints
572
+ ipfs_client = IPFSClient(
573
+ gateway="https://get.hippius.network", # For downloads
574
+ api_url="http://relay-fr.hippius.network:5001" # For uploads
575
+ )
576
+
577
+ # Upload a file
578
+ result = await ipfs_client.upload_file("path/to/your/file.txt")
579
+ cid = result["cid"]
580
+ size = result["size_formatted"]
581
+
582
+ # Upload a directory
583
+ dir_result = await ipfs_client.upload_directory("path/to/your/directory")
584
+ dir_cid = dir_result["cid"]
585
+ file_count = dir_result["file_count"]
586
+ total_size = dir_result["size_formatted"]
587
+
588
+ # Download a file
589
+ dl_result = await ipfs_client.download_file(cid, "path/to/save/file.txt")
590
+ success = dl_result["success"]
591
+ elapsed_time = dl_result["elapsed_seconds"]
592
+
593
+ # Check if a CID exists
594
+ exists_result = await ipfs_client.exists(cid)
595
+ exists = exists_result["exists"]
596
+ gateway_url = exists_result["gateway_url"]
597
+
598
+ # Get file content directly
599
+ content_result = await ipfs_client.cat(cid)
600
+ content = content_result["content"]
601
+ is_text = content_result["is_text"]
602
+ preview = content_result["text_preview"] if is_text else content_result["hex_preview"]
603
+
604
+ # Pin a file
605
+ pin_result = await ipfs_client.pin(cid)
606
+ success = pin_result["success"]
607
+ message = pin_result["message"]
608
+
609
+ # Format a CID (non-async utility function)
610
+ formatted_cid = ipfs_client.format_cid("6261666b7265696134...") # Hex-encoded CID
611
+ # Will return a proper formatted CID like "bafkrei..."
612
+
613
+ # Format a file size (non-async utility function)
614
+ human_readable = ipfs_client.format_size(1048576) # 1 MB
615
+
616
+ # Run the async function
617
+ asyncio.run(main())
587
618
  ```
588
619
 
589
620
  ### IPFS Connection Methods
@@ -665,6 +696,7 @@ hippius config import-env
665
696
  ### Using Configuration in Code
666
697
 
667
698
  ```python
699
+ import asyncio
668
700
  from hippius_sdk import get_config_value, set_config_value, HippiusClient
669
701
 
670
702
  # Get a configuration value
@@ -676,6 +708,13 @@ set_config_value("ipfs", "gateway", "https://dweb.link")
676
708
 
677
709
  # Client will automatically use configuration values
678
710
  client = HippiusClient()
711
+
712
+ async def main():
713
+ # Your async code here
714
+ pass
715
+
716
+ # Run the async function
717
+ asyncio.run(main())
679
718
  ```
680
719
 
681
720
  ## Development
@@ -744,6 +783,7 @@ To test the SDK components, you can create a small test script:
744
783
 
745
784
  ```python
746
785
  # test_script.py
786
+ import asyncio
747
787
  from hippius_sdk import HippiusClient
748
788
  from dotenv import load_dotenv
749
789
  import os
@@ -754,13 +794,17 @@ load_dotenv()
754
794
  # Create a client
755
795
  client = HippiusClient()
756
796
 
757
- # Test a simple operation
758
- print("Testing IPFS client...")
759
- try:
760
- result = client.exists("QmZ4tDuvesekSs4qM5ZBKpXiZGun7S2CYtEZRB3DYXkjGx")
761
- print(f"Result: {result}")
762
- except Exception as e:
763
- print(f"Error: {e}")
797
+ async def test_ipfs_client():
798
+ # Test a simple operation
799
+ print("Testing IPFS client...")
800
+ try:
801
+ result = await client.exists("QmZ4tDuvesekSs4qM5ZBKpXiZGun7S2CYtEZRB3DYXkjGx")
802
+ print(f"Result: {result}")
803
+ except Exception as e:
804
+ print(f"Error: {e}")
805
+
806
+ # Run the async function
807
+ asyncio.run(test_ipfs_client())
764
808
  ```
765
809
 
766
810
  Then run it:
@@ -879,6 +923,7 @@ This provides enhanced security by:
879
923
  When interacting with the Hippius SDK programmatically, you can provide the password when initializing clients:
880
924
 
881
925
  ```python
926
+ import asyncio
882
927
  from hippius_sdk import HippiusClient
883
928
 
884
929
  # The client will prompt for password when needed to decrypt the seed phrase
@@ -886,6 +931,13 @@ client = HippiusClient()
886
931
 
887
932
  # Or you can provide a password when initializing
888
933
  client = HippiusClient(seed_phrase_password="your-password")
934
+
935
+ async def main():
936
+ # Your async code here
937
+ pass
938
+
939
+ # Run the async function
940
+ asyncio.run(main())
889
941
  ```
890
942
 
891
943
  ### Multi-Account Management
@@ -923,25 +975,29 @@ Key features of the multi-account system:
923
975
  To use multiple accounts in your code:
924
976
 
925
977
  ```python
978
+ import asyncio
926
979
  from hippius_sdk import HippiusClient, set_active_account, list_accounts
927
980
 
928
- # List all accounts
929
- accounts = list_accounts()
930
- for name, data in accounts.items():
931
- print(f"{name}: {data.get('ss58_address')}")
932
-
933
- # Switch the active account
934
- set_active_account("my-validator")
935
-
936
- # Create a client with the active account
937
- client = HippiusClient(seed_phrase_password="your-password")
938
-
939
- # Or specify a different account to use
940
- client = HippiusClient(
941
- account_name="my-developer-account",
942
- seed_phrase_password="your-password"
943
- )
981
+ async def main():
982
+ # List all accounts
983
+ accounts = list_accounts()
984
+ for name, data in accounts.items():
985
+ print(f"{name}: {data.get('ss58_address')}")
986
+
987
+ # Switch the active account
988
+ set_active_account("my-validator")
989
+
990
+ # Create a client with the active account
991
+ client = HippiusClient(seed_phrase_password="your-password")
992
+
993
+ # Or specify a different account to use
994
+ client = HippiusClient(
995
+ account_name="my-developer-account",
996
+ seed_phrase_password="your-password"
997
+ )
998
+
999
+ # Run the async function
1000
+ asyncio.run(main())
944
1001
  ```
945
1002
 
946
1003
  The multi-account system makes it easier to manage multiple identities while maintaining security and convenience.
947
-