# 0G Storage Python SDK
**Official Python SDK for 0G Storage** - A decentralized storage network with merkle tree verification.
[]()
[]()
[]()
[]()
Complete line-by-line port of the official TypeScript SDK: [`@0glabs/0g-ts-sdk`](https://github.com/0glabs/0g-ts-sdk)
## ๐ฏ Production Status
โ
**Verified on 0G Testnet**
- Successfully uploaded files (TX: `9f01808921020c29b25e21204bfeb7079ce7cf3dad232e0a6c65451eef82a5f2`)
- Successfully downloaded and verified files
- All 66 unit tests passing
- Merkle roots verified to match TypeScript SDK 100%
โ
**Verified on 0G Mainnet**
- Successfully uploaded files with dynamic storage fee calculation
- Storage fee calculated from market contract (matches TypeScript SDK)
- **Mainnet Upload Proof:**
- File Root Hash: `0x4454572265e0ae600d281a703df306ba7f62e447a9a5526f7f23bf2d4e99cd9d`
- Transaction: `0xeda94ed4698361d5fe61c17d21963e7d2333c15acb190e1b05128272b88882b6`
- Storage Fee: 30,733,644,962 wei (0.0307 OG)
- Full feature parity with TypeScript SDK
โ
**Ready for PyPI Deployment**
- Standard Python packaging
- All dependencies available on PyPI
- Cross-platform compatible (Linux, macOS, Windows)
- Production-grade - used on mainnet
## โจ Features
- ๐ **Cryptographically Verified Merkle Trees** - Identical output to TypeScript SDK
- ๐ค **File Upload** - Submit to blockchain and distribute across storage nodes
- ๐ฅ **File Download** - Retrieve with automatic shard routing
- ๐ **Smart Contract Integration** - Flow contract for on-chain submissions
- ๐ **Sharded Storage** - Optimal node selection using segment tree algorithm
- ๐ **Automatic Retry Logic** - Handles "too many data writing" errors
- โ
**Production Tested** - Real transactions on 0G Storage testnet
## ๐ฆ Installation
### From PyPI (Coming Soon)
```bash
pip install 0g-storage-sdk
```
### From Source
```bash
# Clone repository
git clone <repository-url>
cd 0g_py_storage
# Install dependencies
pip install -r requirements.txt
```
### Requirements
```
pycryptodome>=3.23.0 # Keccak256 hashing
web3>=7.14.0 # Blockchain RPC
eth-account>=0.13.7 # Account management
requests>=2.32.5 # HTTP client
```
## ๐ Quick Start
### 1. Generate Merkle Tree
```python
from core.file import ZgFile
# From file path
file = ZgFile.from_file_path("./data.txt")
tree, err = file.merkle_tree()
if err is None:
print(f"Root Hash: {tree.root_hash()}")
print(f"File Size: {file.size()} bytes")
print(f"Chunks: {file.num_chunks()}")
print(f"Segments: {file.num_segments()}")
file.close()
# From bytes
data = b"Hello, 0G Storage!"
file = ZgFile.from_bytes(data)
tree, err = file.merkle_tree()
print(f"Root Hash: {tree.root_hash()}")
```
### 2. Upload File to 0G Storage
```python
from core.indexer import Indexer
from core.file import ZgFile
from eth_account import Account
# Configuration
INDEXER_RPC = "https://indexer-storage-testnet-turbo.0g.ai"
BLOCKCHAIN_RPC = "https://evmrpc-testnet.0g.ai"
PRIVATE_KEY = "0x..." # Your private key
# Setup
indexer = Indexer(INDEXER_RPC)
account = Account.from_key(PRIVATE_KEY)
file = ZgFile.from_file_path("./data.txt")
# Upload options
upload_opts = {
'tags': b'\x00',
'finalityRequired': True,
'taskSize': 10,
'expectedReplica': 1,
'skipTx': False,
'account': account,
}
# Upload
result, err = indexer.upload(
file,
BLOCKCHAIN_RPC,
account,
upload_opts
)
if err is None:
print(f"โ
Upload successful!")
print(f" Transaction Hash: {result['txHash']}")
print(f" Root Hash: {result['rootHash']}")
else:
print(f"โ Upload failed: {err}")
file.close()
```
**Example Output:**
```
โ
Upload successful!
Transaction Hash: 0x9f01808921020c29b25e21204bfeb7079ce7cf3dad232e0a6c65451eef82a5f2
Root Hash: 0x11fdd3fd0a6e9594bf4ffe86a5cf095d85ac00f23b4f2e559802d624f6a86b58
```
> **Note:** You may see a warning "โ ๏ธ Some direct uploads failed, but file may still propagate via network" - this is normal and the upload succeeds through network propagation.
### 3. Download File from 0G Storage
```python
from core.indexer import Indexer
# Configuration
INDEXER_RPC = "https://indexer-storage-testnet-turbo.0g.ai"
root_hash = "0x11fdd3fd0a6e9594bf4ffe86a5cf095d85ac00f23b4f2e559802d624f6a86b58"
# Download
indexer = Indexer(INDEXER_RPC)
err = indexer.download(root_hash, "./output.txt", proof=False)
if err is None:
print("โ
Download successful!")
else:
print(f"โ Download failed: {err}")
```
**Note:** Files need 3-5 minutes to propagate across storage shards before download.
## ๐๏ธ Architecture
```
0g_py_storage/
โโโ core/
โ โโโ merkle.py # Merkle tree (Keccak256, proof generation)
โ โโโ file.py # File operations & iteration
โ โโโ uploader.py # Upload orchestration with retry logic
โ โโโ downloader.py # Download with shard routing
โ โโโ indexer.py # Indexer RPC client
โ โโโ storage_node.py # Storage node RPC (14 methods)
โ โโโ node_selector.py # Segment tree shard selection
โโโ contracts/
โ โโโ abis.py # Flow contract ABI
โ โโโ flow.py # Flow contract wrapper
โโโ utils/
โ โโโ crypto.py # Keccak256 hashing
โ โโโ http.py # JSON-RPC HTTP client
โ โโโ transfer.py # Transfer utilities
โ โโโ ... # Other utilities
โโโ config.py # Default constants
โโโ requirements.txt # Dependencies
```
## ๐งช Testing
```bash
# Run all tests (66 tests)
pytest tests/ -v
# Run specific test suite
pytest tests/test_merkle.py -v # 26 tests
pytest tests/test_file.py -v # 18 tests
pytest tests/test_node_selector.py -v # 22 tests
# With coverage
pytest tests/ --cov=core --cov=utils
```
**Test Results:**
```
โ
66/66 tests passing
โ
Merkle roots verified against TypeScript SDK
โ
Live network upload successful
โ
Live network download successful
```
## ๐ Verification Against TypeScript SDK
The Python SDK produces **100% identical** merkle roots to the TypeScript SDK:
```bash
# Python verification
python3 verify_against_ts.py
# TypeScript verification
node verify_against_ts.cjs
```
**Verification Results:**
```
Testing with 5 different file sizes...
โ File 1 (256 bytes): Root hashes MATCH
โ File 2 (1024 bytes): Root hashes MATCH
โ File 3 (4096 bytes): Root hashes MATCH
โ File 4 (16384 bytes): Root hashes MATCH
โ File 5 (65536 bytes): Root hashes MATCH
โ
All merkle roots match perfectly!
```
## โ๏ธ Configuration
Default constants (matching TypeScript SDK):
```python
DEFAULT_CHUNK_SIZE = 256 # 256 bytes per chunk
DEFAULT_SEGMENT_SIZE = 262144 # 256 KB per segment (1024 chunks)
DEFAULT_SEGMENT_MAX_CHUNKS = 1024 # Chunks per segment
```
## ๐ API Reference
### ZgFile
```python
# Create file instance
file = ZgFile.from_file_path(path: str) -> ZgFile
file = ZgFile.from_bytes(data: bytes) -> ZgFile
# Generate merkle tree
tree, err = file.merkle_tree() -> Tuple[MerkleTree, Optional[Exception]]
# File information
size = file.size() -> int
chunks = file.num_chunks() -> int
segments = file.num_segments() -> int
# Create blockchain submission
submission, err = file.create_submission(tags: bytes) -> Tuple[dict, Optional[Exception]]
# Cleanup
file.close()
```
### Indexer
```python
# Initialize
indexer = Indexer(url: str)
# Node discovery
nodes = indexer.get_sharded_nodes() -> dict
locations = indexer.get_file_locations(root_hash: str) -> list
clients, err = indexer.select_nodes(expected_replica: int) -> Tuple[list, Optional[Exception]]
# Upload file
result, err = indexer.upload(
file: ZgFile,
blockchain_rpc: str,
signer: Account,
upload_opts: dict,
retry_opts: Optional[dict] = None
) -> Tuple[Optional[dict], Optional[Exception]]
# Download file
err = indexer.download(
root_hash: str,
file_path: str,
proof: bool = False
) -> Optional[Exception]
```
### StorageNode
```python
# Initialize
node = StorageNode(url: str)
# Node operations
status = node.get_status() -> dict
config = node.get_shard_config() -> dict
info = node.get_file_info(root: str, need_available: bool = False) -> dict
# Upload operations
result = node.upload_segment(segment: dict) -> any
result = node.upload_segments(segments: list) -> any
result = node.upload_segments_by_tx_seq(segs: list, tx_seq: int) -> any
# Download operations
data = node.download_segment(root: str, start: int, end: int) -> str
data = node.download_segment_with_proof(root: str, index: int) -> dict
```
### MerkleTree
```python
# Add data
tree.add_leaf(data: bytes)
# Get root hash
root = tree.root_hash() -> str
# Generate proof
proof = tree.proof_at(index: int) -> Proof
# Validate proof
is_valid = proof.validate(root: str, data: bytes, index: int, proof_check: Proof) -> Tuple[bool, Optional[Exception]]
```
## ๐ Network Configuration
### Testnet
```python
BLOCKCHAIN_RPC = "https://evmrpc-testnet.0g.ai"
INDEXER_RPC = "https://indexer-storage-testnet-turbo.0g.ai"
FLOW_CONTRACT = "0x22e03a6a89b950f1c82ec5e74f8eca321a105296"
CHAIN_ID = 16602
```
### Mainnet
```python
BLOCKCHAIN_RPC = "https://evmrpc.0g.ai"
INDEXER_RPC = "https://indexer-storage-turbo.0g.ai"
FLOW_CONTRACT = "0x62D4144dB0F0a6fBBaeb6296c785C71B3D57C526"
CHAIN_ID = 16661
```
**Status: โ
Production Ready**
- Fully tested and working on mainnet
- Dynamic storage fee calculation from market contract
- All 66 unit tests passing
**Real Mainnet Upload Verification:**
```
File Root Hash: 0x4454572265e0ae600d281a703df306ba7f62e447a9a5526f7f23bf2d4e99cd9d
Transaction Hash: 0xeda94ed4698361d5fe61c17d21963e7d2333c15acb190e1b05128272b88882b6
Block: 10,998,900
Storage Fee: 30,733,644,962 wei
Status: โ
Confirmed
```
View the transaction: https://chainscan.0g.ai/tx/0xeda94ed4698361d5fe61c17d21963e7d2333c15acb190e1b05128272b88882b6
## ๐ฌ Development
### Implementation Phases
- โ
**Phase 1:** Foundation (config, utils, exceptions)
- โ
**Phase 2:** Models (transaction, node, file)
- โ
**Phase 3:** Core Cryptography (merkle tree)
- โ
**Phase 4:** Smart Contracts (flow contract)
- โ
**Phase 5:** File Operations (file iteration)
- โ
**Phase 6:** Network Layer (indexer, storage nodes)
- โ
**Phase 7:** Upload (uploader with retry logic)
- โ
**Phase 8:** Download (downloader with shard routing)
### Code Quality
- โ
Line-by-line port from TypeScript SDK
- โ
Maintains exact same behavior
- โ
66 comprehensive tests (100% passing)
- โ
Type hints throughout
- โ
Detailed documentation with TS SDK line references
### Example Code Structure
```python
def upload_task(self, file, tree, upload_task, retry_opts):
"""
Upload a single task (batch of segments).
TS SDK lines 315-381. # โ References exact TypeScript lines
Args:
file: File object
tree: Merkle tree
upload_task: Task definition
retry_opts: Retry options
"""
# Implementation matches TS SDK exactly...
```
## ๐ค Contributing
This SDK is a direct port of the official TypeScript SDK. Contributions should:
1. **Match TypeScript SDK behavior** - Verify outputs match
2. **Include tests** - Add corresponding test cases
3. **Update documentation** - Keep README current
4. **Reference TS SDK** - Include line number references
## ๐ License
Same license as the official TypeScript SDK.
## ๐ Links
- **TypeScript SDK:** https://github.com/0glabs/0g-ts-sdk
- **0G Storage Docs:** https://docs.0g.ai
- **0G Website:** https://0g.ai
- **Testnet Explorer:** https://chainscan-galileo.0g.ai/
## ๐ Support
For Python SDK issues:
- Open an issue with Python version, error message, and minimal reproduction code
- Include comparison with TypeScript SDK behavior if applicable
For 0G Storage general questions:
- Check official documentation: https://docs.0g.ai
- Join 0G community channels
## ๐ Status
| Component | Status | Tests | TypeScript Parity |
|-----------|--------|-------|-------------------|
| Merkle Tree | โ
Production | 26/26 | 100% |
| File Operations | โ
Production | 18/18 | 100% |
| Node Selection | โ
Production | 22/22 | 100% |
| Upload | โ
Production | Verified | 100% |
| Download | โ
Production | Verified | 100% |
| Contract Integration | โ
Production | Verified | 100% |
**Last Verified:** Transaction `9f01808921020c29b25e21204bfeb7079ce7cf3dad232e0a6c65451eef82a5f2` on 0G Testnet
---
**Built with โค๏ธ for the 0G Storage ecosystem**
Raw data
{
"_id": null,
"home_page": "https://github.com/0glabs/0g-py-sdk",
"name": "0g-storage-sdk",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "0g storage blockchain web3 merkle cryptography decentralized",
"author": "0G Labs",
"author_email": "support@0g.ai",
"download_url": "https://files.pythonhosted.org/packages/e9/a1/c3690c95cc40347ee2cf5c9b7c0cf469803ca9821bbc3fe451ef8cbaedf2/0g_storage_sdk-0.2.1.tar.gz",
"platform": null,
"description": "# 0G Storage Python SDK\n\n**Official Python SDK for 0G Storage** - A decentralized storage network with merkle tree verification.\n\n[]()\n[]()\n[]()\n[]()\n\nComplete line-by-line port of the official TypeScript SDK: [`@0glabs/0g-ts-sdk`](https://github.com/0glabs/0g-ts-sdk)\n\n## \ud83c\udfaf Production Status\n\n\u2705 **Verified on 0G Testnet**\n- Successfully uploaded files (TX: `9f01808921020c29b25e21204bfeb7079ce7cf3dad232e0a6c65451eef82a5f2`)\n- Successfully downloaded and verified files\n- All 66 unit tests passing\n- Merkle roots verified to match TypeScript SDK 100%\n\n\u2705 **Verified on 0G Mainnet**\n- Successfully uploaded files with dynamic storage fee calculation\n- Storage fee calculated from market contract (matches TypeScript SDK)\n- **Mainnet Upload Proof:**\n - File Root Hash: `0x4454572265e0ae600d281a703df306ba7f62e447a9a5526f7f23bf2d4e99cd9d`\n - Transaction: `0xeda94ed4698361d5fe61c17d21963e7d2333c15acb190e1b05128272b88882b6`\n - Storage Fee: 30,733,644,962 wei (0.0307 OG)\n- Full feature parity with TypeScript SDK\n\n\u2705 **Ready for PyPI Deployment**\n- Standard Python packaging\n- All dependencies available on PyPI\n- Cross-platform compatible (Linux, macOS, Windows)\n- Production-grade - used on mainnet\n\n## \u2728 Features\n\n- \ud83d\udd10 **Cryptographically Verified Merkle Trees** - Identical output to TypeScript SDK\n- \ud83d\udce4 **File Upload** - Submit to blockchain and distribute across storage nodes\n- \ud83d\udce5 **File Download** - Retrieve with automatic shard routing\n- \ud83d\udd17 **Smart Contract Integration** - Flow contract for on-chain submissions\n- \ud83c\udf10 **Sharded Storage** - Optimal node selection using segment tree algorithm\n- \ud83d\udd04 **Automatic Retry Logic** - Handles \"too many data writing\" errors\n- \u2705 **Production Tested** - Real transactions on 0G Storage testnet\n\n## \ud83d\udce6 Installation\n\n### From PyPI (Coming Soon)\n\n```bash\npip install 0g-storage-sdk\n```\n\n### From Source\n\n```bash\n# Clone repository\ngit clone <repository-url>\ncd 0g_py_storage\n\n# Install dependencies\npip install -r requirements.txt\n```\n\n### Requirements\n\n```\npycryptodome>=3.23.0 # Keccak256 hashing\nweb3>=7.14.0 # Blockchain RPC\neth-account>=0.13.7 # Account management\nrequests>=2.32.5 # HTTP client\n```\n\n## \ud83d\ude80 Quick Start\n\n### 1. Generate Merkle Tree\n\n```python\nfrom core.file import ZgFile\n\n# From file path\nfile = ZgFile.from_file_path(\"./data.txt\")\ntree, err = file.merkle_tree()\n\nif err is None:\n print(f\"Root Hash: {tree.root_hash()}\")\n print(f\"File Size: {file.size()} bytes\")\n print(f\"Chunks: {file.num_chunks()}\")\n print(f\"Segments: {file.num_segments()}\")\n\nfile.close()\n\n# From bytes\ndata = b\"Hello, 0G Storage!\"\nfile = ZgFile.from_bytes(data)\ntree, err = file.merkle_tree()\nprint(f\"Root Hash: {tree.root_hash()}\")\n```\n\n### 2. Upload File to 0G Storage\n\n```python\nfrom core.indexer import Indexer\nfrom core.file import ZgFile\nfrom eth_account import Account\n\n# Configuration\nINDEXER_RPC = \"https://indexer-storage-testnet-turbo.0g.ai\"\nBLOCKCHAIN_RPC = \"https://evmrpc-testnet.0g.ai\"\nPRIVATE_KEY = \"0x...\" # Your private key\n\n# Setup\nindexer = Indexer(INDEXER_RPC)\naccount = Account.from_key(PRIVATE_KEY)\nfile = ZgFile.from_file_path(\"./data.txt\")\n\n# Upload options\nupload_opts = {\n 'tags': b'\\x00',\n 'finalityRequired': True,\n 'taskSize': 10,\n 'expectedReplica': 1,\n 'skipTx': False,\n 'account': account,\n}\n\n# Upload\nresult, err = indexer.upload(\n file,\n BLOCKCHAIN_RPC,\n account,\n upload_opts\n)\n\nif err is None:\n print(f\"\u2705 Upload successful!\")\n print(f\" Transaction Hash: {result['txHash']}\")\n print(f\" Root Hash: {result['rootHash']}\")\nelse:\n print(f\"\u274c Upload failed: {err}\")\n\nfile.close()\n```\n\n**Example Output:**\n```\n\u2705 Upload successful!\n Transaction Hash: 0x9f01808921020c29b25e21204bfeb7079ce7cf3dad232e0a6c65451eef82a5f2\n Root Hash: 0x11fdd3fd0a6e9594bf4ffe86a5cf095d85ac00f23b4f2e559802d624f6a86b58\n```\n\n> **Note:** You may see a warning \"\u26a0\ufe0f Some direct uploads failed, but file may still propagate via network\" - this is normal and the upload succeeds through network propagation.\n\n### 3. Download File from 0G Storage\n\n```python\nfrom core.indexer import Indexer\n\n# Configuration\nINDEXER_RPC = \"https://indexer-storage-testnet-turbo.0g.ai\"\nroot_hash = \"0x11fdd3fd0a6e9594bf4ffe86a5cf095d85ac00f23b4f2e559802d624f6a86b58\"\n\n# Download\nindexer = Indexer(INDEXER_RPC)\nerr = indexer.download(root_hash, \"./output.txt\", proof=False)\n\nif err is None:\n print(\"\u2705 Download successful!\")\nelse:\n print(f\"\u274c Download failed: {err}\")\n```\n\n**Note:** Files need 3-5 minutes to propagate across storage shards before download.\n\n## \ud83c\udfd7\ufe0f Architecture\n\n```\n0g_py_storage/\n\u251c\u2500\u2500 core/\n\u2502 \u251c\u2500\u2500 merkle.py # Merkle tree (Keccak256, proof generation)\n\u2502 \u251c\u2500\u2500 file.py # File operations & iteration\n\u2502 \u251c\u2500\u2500 uploader.py # Upload orchestration with retry logic\n\u2502 \u251c\u2500\u2500 downloader.py # Download with shard routing\n\u2502 \u251c\u2500\u2500 indexer.py # Indexer RPC client\n\u2502 \u251c\u2500\u2500 storage_node.py # Storage node RPC (14 methods)\n\u2502 \u2514\u2500\u2500 node_selector.py # Segment tree shard selection\n\u251c\u2500\u2500 contracts/\n\u2502 \u251c\u2500\u2500 abis.py # Flow contract ABI\n\u2502 \u2514\u2500\u2500 flow.py # Flow contract wrapper\n\u251c\u2500\u2500 utils/\n\u2502 \u251c\u2500\u2500 crypto.py # Keccak256 hashing\n\u2502 \u251c\u2500\u2500 http.py # JSON-RPC HTTP client\n\u2502 \u251c\u2500\u2500 transfer.py # Transfer utilities\n\u2502 \u2514\u2500\u2500 ... # Other utilities\n\u251c\u2500\u2500 config.py # Default constants\n\u2514\u2500\u2500 requirements.txt # Dependencies\n```\n\n## \ud83e\uddea Testing\n\n```bash\n# Run all tests (66 tests)\npytest tests/ -v\n\n# Run specific test suite\npytest tests/test_merkle.py -v # 26 tests\npytest tests/test_file.py -v # 18 tests\npytest tests/test_node_selector.py -v # 22 tests\n\n# With coverage\npytest tests/ --cov=core --cov=utils\n```\n\n**Test Results:**\n```\n\u2705 66/66 tests passing\n\u2705 Merkle roots verified against TypeScript SDK\n\u2705 Live network upload successful\n\u2705 Live network download successful\n```\n\n## \ud83d\udd0d Verification Against TypeScript SDK\n\nThe Python SDK produces **100% identical** merkle roots to the TypeScript SDK:\n\n```bash\n# Python verification\npython3 verify_against_ts.py\n\n# TypeScript verification\nnode verify_against_ts.cjs\n```\n\n**Verification Results:**\n```\nTesting with 5 different file sizes...\n\u2713 File 1 (256 bytes): Root hashes MATCH\n\u2713 File 2 (1024 bytes): Root hashes MATCH\n\u2713 File 3 (4096 bytes): Root hashes MATCH\n\u2713 File 4 (16384 bytes): Root hashes MATCH\n\u2713 File 5 (65536 bytes): Root hashes MATCH\n\n\u2705 All merkle roots match perfectly!\n```\n\n## \u2699\ufe0f Configuration\n\nDefault constants (matching TypeScript SDK):\n\n```python\nDEFAULT_CHUNK_SIZE = 256 # 256 bytes per chunk\nDEFAULT_SEGMENT_SIZE = 262144 # 256 KB per segment (1024 chunks)\nDEFAULT_SEGMENT_MAX_CHUNKS = 1024 # Chunks per segment\n```\n\n## \ud83d\udcda API Reference\n\n### ZgFile\n\n```python\n# Create file instance\nfile = ZgFile.from_file_path(path: str) -> ZgFile\nfile = ZgFile.from_bytes(data: bytes) -> ZgFile\n\n# Generate merkle tree\ntree, err = file.merkle_tree() -> Tuple[MerkleTree, Optional[Exception]]\n\n# File information\nsize = file.size() -> int\nchunks = file.num_chunks() -> int\nsegments = file.num_segments() -> int\n\n# Create blockchain submission\nsubmission, err = file.create_submission(tags: bytes) -> Tuple[dict, Optional[Exception]]\n\n# Cleanup\nfile.close()\n```\n\n### Indexer\n\n```python\n# Initialize\nindexer = Indexer(url: str)\n\n# Node discovery\nnodes = indexer.get_sharded_nodes() -> dict\nlocations = indexer.get_file_locations(root_hash: str) -> list\nclients, err = indexer.select_nodes(expected_replica: int) -> Tuple[list, Optional[Exception]]\n\n# Upload file\nresult, err = indexer.upload(\n file: ZgFile,\n blockchain_rpc: str,\n signer: Account,\n upload_opts: dict,\n retry_opts: Optional[dict] = None\n) -> Tuple[Optional[dict], Optional[Exception]]\n\n# Download file\nerr = indexer.download(\n root_hash: str,\n file_path: str,\n proof: bool = False\n) -> Optional[Exception]\n```\n\n### StorageNode\n\n```python\n# Initialize\nnode = StorageNode(url: str)\n\n# Node operations\nstatus = node.get_status() -> dict\nconfig = node.get_shard_config() -> dict\ninfo = node.get_file_info(root: str, need_available: bool = False) -> dict\n\n# Upload operations\nresult = node.upload_segment(segment: dict) -> any\nresult = node.upload_segments(segments: list) -> any\nresult = node.upload_segments_by_tx_seq(segs: list, tx_seq: int) -> any\n\n# Download operations\ndata = node.download_segment(root: str, start: int, end: int) -> str\ndata = node.download_segment_with_proof(root: str, index: int) -> dict\n```\n\n### MerkleTree\n\n```python\n# Add data\ntree.add_leaf(data: bytes)\n\n# Get root hash\nroot = tree.root_hash() -> str\n\n# Generate proof\nproof = tree.proof_at(index: int) -> Proof\n\n# Validate proof\nis_valid = proof.validate(root: str, data: bytes, index: int, proof_check: Proof) -> Tuple[bool, Optional[Exception]]\n```\n\n## \ud83c\udf10 Network Configuration\n\n### Testnet\n\n```python\nBLOCKCHAIN_RPC = \"https://evmrpc-testnet.0g.ai\"\nINDEXER_RPC = \"https://indexer-storage-testnet-turbo.0g.ai\"\nFLOW_CONTRACT = \"0x22e03a6a89b950f1c82ec5e74f8eca321a105296\"\nCHAIN_ID = 16602\n```\n\n### Mainnet\n\n```python\nBLOCKCHAIN_RPC = \"https://evmrpc.0g.ai\"\nINDEXER_RPC = \"https://indexer-storage-turbo.0g.ai\"\nFLOW_CONTRACT = \"0x62D4144dB0F0a6fBBaeb6296c785C71B3D57C526\"\nCHAIN_ID = 16661\n```\n\n**Status: \u2705 Production Ready**\n- Fully tested and working on mainnet\n- Dynamic storage fee calculation from market contract\n- All 66 unit tests passing\n\n**Real Mainnet Upload Verification:**\n```\nFile Root Hash: 0x4454572265e0ae600d281a703df306ba7f62e447a9a5526f7f23bf2d4e99cd9d\nTransaction Hash: 0xeda94ed4698361d5fe61c17d21963e7d2333c15acb190e1b05128272b88882b6\nBlock: 10,998,900\nStorage Fee: 30,733,644,962 wei\nStatus: \u2705 Confirmed\n```\n\nView the transaction: https://chainscan.0g.ai/tx/0xeda94ed4698361d5fe61c17d21963e7d2333c15acb190e1b05128272b88882b6\n\n## \ud83d\udd2c Development\n\n### Implementation Phases\n\n- \u2705 **Phase 1:** Foundation (config, utils, exceptions)\n- \u2705 **Phase 2:** Models (transaction, node, file)\n- \u2705 **Phase 3:** Core Cryptography (merkle tree)\n- \u2705 **Phase 4:** Smart Contracts (flow contract)\n- \u2705 **Phase 5:** File Operations (file iteration)\n- \u2705 **Phase 6:** Network Layer (indexer, storage nodes)\n- \u2705 **Phase 7:** Upload (uploader with retry logic)\n- \u2705 **Phase 8:** Download (downloader with shard routing)\n\n### Code Quality\n\n- \u2705 Line-by-line port from TypeScript SDK\n- \u2705 Maintains exact same behavior\n- \u2705 66 comprehensive tests (100% passing)\n- \u2705 Type hints throughout\n- \u2705 Detailed documentation with TS SDK line references\n\n### Example Code Structure\n\n```python\ndef upload_task(self, file, tree, upload_task, retry_opts):\n \"\"\"\n Upload a single task (batch of segments).\n\n TS SDK lines 315-381. # \u2190 References exact TypeScript lines\n\n Args:\n file: File object\n tree: Merkle tree\n upload_task: Task definition\n retry_opts: Retry options\n \"\"\"\n # Implementation matches TS SDK exactly...\n```\n\n## \ud83e\udd1d Contributing\n\nThis SDK is a direct port of the official TypeScript SDK. Contributions should:\n\n1. **Match TypeScript SDK behavior** - Verify outputs match\n2. **Include tests** - Add corresponding test cases\n3. **Update documentation** - Keep README current\n4. **Reference TS SDK** - Include line number references\n\n## \ud83d\udcc4 License\n\nSame license as the official TypeScript SDK.\n\n## \ud83d\udd17 Links\n\n- **TypeScript SDK:** https://github.com/0glabs/0g-ts-sdk\n- **0G Storage Docs:** https://docs.0g.ai\n- **0G Website:** https://0g.ai\n- **Testnet Explorer:** https://chainscan-galileo.0g.ai/\n\n## \ud83c\udd98 Support\n\nFor Python SDK issues:\n- Open an issue with Python version, error message, and minimal reproduction code\n- Include comparison with TypeScript SDK behavior if applicable\n\nFor 0G Storage general questions:\n- Check official documentation: https://docs.0g.ai\n- Join 0G community channels\n\n## \ud83d\udcca Status\n\n| Component | Status | Tests | TypeScript Parity |\n|-----------|--------|-------|-------------------|\n| Merkle Tree | \u2705 Production | 26/26 | 100% |\n| File Operations | \u2705 Production | 18/18 | 100% |\n| Node Selection | \u2705 Production | 22/22 | 100% |\n| Upload | \u2705 Production | Verified | 100% |\n| Download | \u2705 Production | Verified | 100% |\n| Contract Integration | \u2705 Production | Verified | 100% |\n\n**Last Verified:** Transaction `9f01808921020c29b25e21204bfeb7079ce7cf3dad232e0a6c65451eef82a5f2` on 0G Testnet\n\n---\n\n**Built with \u2764\ufe0f for the 0G Storage ecosystem**\n",
"bugtrack_url": null,
"license": null,
"summary": "Official Python SDK for 0G Storage - A decentralized storage network with merkle tree verification",
"version": "0.2.1",
"project_urls": {
"Bug Tracker": "https://github.com/0glabs/0g-py-sdk/issues",
"Documentation": "https://docs.0g.ai",
"Homepage": "https://github.com/0glabs/0g-py-sdk",
"Source Code": "https://github.com/0glabs/0g-py-sdk/tree/main/0g_py_storage"
},
"split_keywords": [
"0g",
"storage",
"blockchain",
"web3",
"merkle",
"cryptography",
"decentralized"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "e9a1c3690c95cc40347ee2cf5c9b7c0cf469803ca9821bbc3fe451ef8cbaedf2",
"md5": "2ed7ff712e90e6f29135dee6073664d7",
"sha256": "5efc34bd4ed7ad3c318d934994d49d7b2e3b35f0f395f2270b0f8014359c3b9c"
},
"downloads": -1,
"filename": "0g_storage_sdk-0.2.1.tar.gz",
"has_sig": false,
"md5_digest": "2ed7ff712e90e6f29135dee6073664d7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 41240,
"upload_time": "2025-10-31T00:53:11",
"upload_time_iso_8601": "2025-10-31T00:53:11.520752Z",
"url": "https://files.pythonhosted.org/packages/e9/a1/c3690c95cc40347ee2cf5c9b7c0cf469803ca9821bbc3fe451ef8cbaedf2/0g_storage_sdk-0.2.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-31 00:53:11",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "0glabs",
"github_project": "0g-py-sdk",
"github_not_found": true,
"lcname": "0g-storage-sdk"
}