synapse-filecoin-sdk 0.1.1__py3-none-any.whl → 0.2.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.
- pynapse/_version.py +1 -1
- pynapse/integrations/__init__.py +4 -0
- pynapse/integrations/langchain.py +214 -0
- {synapse_filecoin_sdk-0.1.1.dist-info → synapse_filecoin_sdk-0.2.0.dist-info}/METADATA +29 -3
- {synapse_filecoin_sdk-0.1.1.dist-info → synapse_filecoin_sdk-0.2.0.dist-info}/RECORD +7 -5
- {synapse_filecoin_sdk-0.1.1.dist-info → synapse_filecoin_sdk-0.2.0.dist-info}/WHEEL +0 -0
- {synapse_filecoin_sdk-0.1.1.dist-info → synapse_filecoin_sdk-0.2.0.dist-info}/licenses/LICENSE.md +0 -0
pynapse/_version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "0.2.0"
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LangChain integration for pynapse.
|
|
3
|
+
|
|
4
|
+
This module provides LangChain-compatible components for storing and loading
|
|
5
|
+
documents on Filecoin via the Synapse SDK.
|
|
6
|
+
|
|
7
|
+
Installation:
|
|
8
|
+
pip install synapse-filecoin-sdk[langchain]
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
from pynapse.integrations.langchain import FilecoinDocumentLoader, FilecoinStorageTool
|
|
12
|
+
|
|
13
|
+
# Load documents from Filecoin
|
|
14
|
+
loader = FilecoinDocumentLoader(
|
|
15
|
+
rpc_url="https://api.node.glif.io/rpc/v1",
|
|
16
|
+
chain="mainnet",
|
|
17
|
+
private_key=PRIVATE_KEY
|
|
18
|
+
)
|
|
19
|
+
docs = await loader.aload(piece_cid="baga6ea4seaq...")
|
|
20
|
+
|
|
21
|
+
# Store documents on Filecoin (as a LangChain tool for agents)
|
|
22
|
+
tool = FilecoinStorageTool(
|
|
23
|
+
rpc_url="https://api.node.glif.io/rpc/v1",
|
|
24
|
+
chain="mainnet",
|
|
25
|
+
private_key=PRIVATE_KEY
|
|
26
|
+
)
|
|
27
|
+
result = await tool._arun(content="Hello, Filecoin!")
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
from __future__ import annotations
|
|
31
|
+
|
|
32
|
+
import asyncio
|
|
33
|
+
from typing import Any, Dict, List, Optional, Type
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
from langchain_core.documents import Document
|
|
37
|
+
from langchain_core.document_loaders import BaseLoader
|
|
38
|
+
from langchain_core.tools import BaseTool
|
|
39
|
+
from pydantic import BaseModel, Field
|
|
40
|
+
except ImportError as e:
|
|
41
|
+
raise ImportError(
|
|
42
|
+
"LangChain dependencies not installed. "
|
|
43
|
+
"Install with: pip install synapse-filecoin-sdk[langchain]"
|
|
44
|
+
) from e
|
|
45
|
+
|
|
46
|
+
from pynapse import AsyncSynapse
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class FilecoinDocumentLoader(BaseLoader):
|
|
50
|
+
"""Load documents from Filecoin using pynapse.
|
|
51
|
+
|
|
52
|
+
This loader retrieves data stored on Filecoin by Piece CID and converts
|
|
53
|
+
it into LangChain Document objects.
|
|
54
|
+
|
|
55
|
+
Example:
|
|
56
|
+
loader = FilecoinDocumentLoader(
|
|
57
|
+
rpc_url="https://api.node.glif.io/rpc/v1",
|
|
58
|
+
chain="mainnet",
|
|
59
|
+
private_key="0x..."
|
|
60
|
+
)
|
|
61
|
+
docs = await loader.aload(piece_cid="baga6ea4seaq...")
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def __init__(
|
|
65
|
+
self,
|
|
66
|
+
rpc_url: str,
|
|
67
|
+
chain: str = "mainnet",
|
|
68
|
+
private_key: Optional[str] = None,
|
|
69
|
+
):
|
|
70
|
+
"""Initialize the Filecoin document loader.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
rpc_url: RPC URL for Filecoin node
|
|
74
|
+
chain: Network name ("mainnet" or "calibration")
|
|
75
|
+
private_key: Wallet private key (optional for read-only operations)
|
|
76
|
+
"""
|
|
77
|
+
self.rpc_url = rpc_url
|
|
78
|
+
self.chain = chain
|
|
79
|
+
self.private_key = private_key
|
|
80
|
+
self._synapse: Optional[AsyncSynapse] = None
|
|
81
|
+
|
|
82
|
+
async def _get_synapse(self) -> AsyncSynapse:
|
|
83
|
+
"""Get or create AsyncSynapse instance."""
|
|
84
|
+
if self._synapse is None:
|
|
85
|
+
self._synapse = await AsyncSynapse.create(
|
|
86
|
+
rpc_url=self.rpc_url,
|
|
87
|
+
chain=self.chain,
|
|
88
|
+
private_key=self.private_key,
|
|
89
|
+
)
|
|
90
|
+
return self._synapse
|
|
91
|
+
|
|
92
|
+
def load(self) -> List[Document]:
|
|
93
|
+
"""Synchronous load - not supported, use aload instead."""
|
|
94
|
+
raise NotImplementedError(
|
|
95
|
+
"FilecoinDocumentLoader is async-only. Use aload() instead."
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
async def aload(self, piece_cid: str) -> List[Document]:
|
|
99
|
+
"""Load a document from Filecoin by Piece CID.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
piece_cid: The Piece CID of the stored data
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
List containing a single Document with the retrieved content
|
|
106
|
+
"""
|
|
107
|
+
synapse = await self._get_synapse()
|
|
108
|
+
ctx = await synapse.storage.get_context()
|
|
109
|
+
|
|
110
|
+
# Download the data
|
|
111
|
+
data = await ctx.download(piece_cid)
|
|
112
|
+
|
|
113
|
+
# Try to decode as text, fall back to repr for binary
|
|
114
|
+
try:
|
|
115
|
+
content = data.decode("utf-8")
|
|
116
|
+
except UnicodeDecodeError:
|
|
117
|
+
content = repr(data)
|
|
118
|
+
|
|
119
|
+
return [
|
|
120
|
+
Document(
|
|
121
|
+
page_content=content,
|
|
122
|
+
metadata={
|
|
123
|
+
"source": f"filecoin://{piece_cid}",
|
|
124
|
+
"piece_cid": piece_cid,
|
|
125
|
+
"chain": self.chain,
|
|
126
|
+
"size": len(data),
|
|
127
|
+
}
|
|
128
|
+
)
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class FilecoinStorageInput(BaseModel):
|
|
133
|
+
"""Input schema for FilecoinStorageTool."""
|
|
134
|
+
content: str = Field(description="The text content to store on Filecoin")
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class FilecoinStorageTool(BaseTool):
|
|
138
|
+
"""LangChain tool for storing data on Filecoin.
|
|
139
|
+
|
|
140
|
+
This tool allows LangChain agents to store arbitrary text content on
|
|
141
|
+
Filecoin and returns the Piece CID for later retrieval.
|
|
142
|
+
|
|
143
|
+
Example:
|
|
144
|
+
tool = FilecoinStorageTool(
|
|
145
|
+
rpc_url="https://api.node.glif.io/rpc/v1",
|
|
146
|
+
chain="mainnet",
|
|
147
|
+
private_key="0x..."
|
|
148
|
+
)
|
|
149
|
+
# Use in an agent or call directly
|
|
150
|
+
result = await tool._arun(content="Store this on Filecoin!")
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
name: str = "filecoin_storage"
|
|
154
|
+
description: str = (
|
|
155
|
+
"Store text content on Filecoin decentralized storage. "
|
|
156
|
+
"Returns the Piece CID which can be used to retrieve the content later. "
|
|
157
|
+
"Use this when you need to permanently store data on decentralized storage."
|
|
158
|
+
)
|
|
159
|
+
args_schema: Type[BaseModel] = FilecoinStorageInput
|
|
160
|
+
|
|
161
|
+
rpc_url: str
|
|
162
|
+
chain: str = "mainnet"
|
|
163
|
+
private_key: str
|
|
164
|
+
_synapse: Optional[AsyncSynapse] = None
|
|
165
|
+
|
|
166
|
+
class Config:
|
|
167
|
+
arbitrary_types_allowed = True
|
|
168
|
+
|
|
169
|
+
async def _get_synapse(self) -> AsyncSynapse:
|
|
170
|
+
"""Get or create AsyncSynapse instance."""
|
|
171
|
+
if self._synapse is None:
|
|
172
|
+
self._synapse = await AsyncSynapse.create(
|
|
173
|
+
rpc_url=self.rpc_url,
|
|
174
|
+
chain=self.chain,
|
|
175
|
+
private_key=self.private_key,
|
|
176
|
+
)
|
|
177
|
+
return self._synapse
|
|
178
|
+
|
|
179
|
+
def _run(self, content: str) -> str:
|
|
180
|
+
"""Synchronous run - wraps async implementation."""
|
|
181
|
+
return asyncio.run(self._arun(content=content))
|
|
182
|
+
|
|
183
|
+
async def _arun(self, content: str) -> str:
|
|
184
|
+
"""Store content on Filecoin and return the Piece CID.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
content: Text content to store
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
JSON string with piece_cid, size, and tx_hash
|
|
191
|
+
"""
|
|
192
|
+
synapse = await self._get_synapse()
|
|
193
|
+
ctx = await synapse.storage.get_context()
|
|
194
|
+
|
|
195
|
+
# Encode content and ensure minimum size (256 bytes)
|
|
196
|
+
data = content.encode("utf-8")
|
|
197
|
+
if len(data) < 256:
|
|
198
|
+
data = data + b'\x00' * (256 - len(data))
|
|
199
|
+
|
|
200
|
+
# Upload to Filecoin
|
|
201
|
+
result = await ctx.upload(data)
|
|
202
|
+
|
|
203
|
+
return (
|
|
204
|
+
f'{{"piece_cid": "{result.piece_cid}", '
|
|
205
|
+
f'"size": {result.size}, '
|
|
206
|
+
f'"tx_hash": "{result.tx_hash}"}}'
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
__all__ = [
|
|
211
|
+
"FilecoinDocumentLoader",
|
|
212
|
+
"FilecoinStorageTool",
|
|
213
|
+
"FilecoinStorageInput",
|
|
214
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: synapse-filecoin-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Python SDK for Filecoin Onchain Cloud (Synapse)
|
|
5
5
|
Project-URL: Homepage, https://github.com/anjor/pynapse
|
|
6
6
|
Project-URL: Repository, https://github.com/anjor/pynapse
|
|
@@ -18,6 +18,8 @@ Requires-Python: >=3.11
|
|
|
18
18
|
Requires-Dist: httpx<0.28.0,>=0.25.0
|
|
19
19
|
Requires-Dist: multiformats<0.4.0,>=0.3.1
|
|
20
20
|
Requires-Dist: web3<7,>=6.0.0
|
|
21
|
+
Provides-Extra: langchain
|
|
22
|
+
Requires-Dist: langchain-core<0.4,>=0.1.0; extra == 'langchain'
|
|
21
23
|
Provides-Extra: test
|
|
22
24
|
Requires-Dist: pytest-asyncio<0.24,>=0.23.0; extra == 'test'
|
|
23
25
|
Requires-Dist: pytest<9,>=8.0.0; extra == 'test'
|
|
@@ -49,6 +51,30 @@ Python import: `pynapse`
|
|
|
49
51
|
pip install synapse-filecoin-sdk
|
|
50
52
|
```
|
|
51
53
|
|
|
54
|
+
## Supported Networks
|
|
55
|
+
|
|
56
|
+
Both **Filecoin Mainnet** and **Calibration testnet** are supported:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from pynapse import AsyncSynapse
|
|
60
|
+
|
|
61
|
+
# Mainnet
|
|
62
|
+
synapse = await AsyncSynapse.create(
|
|
63
|
+
rpc_url="https://api.node.glif.io/rpc/v1",
|
|
64
|
+
chain="mainnet",
|
|
65
|
+
private_key=PRIVATE_KEY
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
# Calibration testnet (for testing)
|
|
69
|
+
synapse = await AsyncSynapse.create(
|
|
70
|
+
rpc_url="https://api.calibration.node.glif.io/rpc/v1",
|
|
71
|
+
chain="calibration",
|
|
72
|
+
private_key=PRIVATE_KEY
|
|
73
|
+
)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
See [QUICKSTART.md](QUICKSTART.md) for a full tutorial using Calibration testnet.
|
|
77
|
+
|
|
52
78
|
## CommP / PieceCID
|
|
53
79
|
|
|
54
80
|
`pynapse` uses `stream-commp` from `go-fil-commp-hashhash` for PieceCID calculation.
|
|
@@ -88,8 +114,8 @@ Publishing is automated via GitHub Actions in `.github/workflows/publish-pypi.ym
|
|
|
88
114
|
3. Tag a release and push the tag:
|
|
89
115
|
|
|
90
116
|
```bash
|
|
91
|
-
git tag v0.
|
|
92
|
-
git push origin v0.
|
|
117
|
+
git tag v0.2.0
|
|
118
|
+
git push origin v0.2.0
|
|
93
119
|
```
|
|
94
120
|
|
|
95
121
|
The workflow builds the package, runs `twine check`, and publishes to PyPI via OIDC (no API token required).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
pynapse/__init__.py,sha256=EcNT2_edj2ICiSNlOjdiRTOsqSn4pK5-W0MCfMEHfEA,187
|
|
2
|
-
pynapse/_version.py,sha256=
|
|
2
|
+
pynapse/_version.py,sha256=Zn1KFblwuFHiDRdRAiRnDBRkbPttWh44jKa5zG2ov0E,22
|
|
3
3
|
pynapse/synapse.py,sha256=crjmmtfFfQzRg4iZqwAOe9JOF-ddNi0PV432XQTyNNk,6582
|
|
4
4
|
pynapse/contracts/__init__.py,sha256=8nz_zyobw86VKfzw7sZaoHrvf_YD8WrDuh89UdeEHLQ,757
|
|
5
5
|
pynapse/contracts/abi_registry.py,sha256=PJQalwqabJWWdC65SUJUxIGz1f5zBxHbdyTQD3azckU,219
|
|
@@ -28,6 +28,8 @@ pynapse/evm/__init__.py,sha256=4lPmHfNArjp-QfYg-SpL6NzkoQ8JeSM3LsvjEMqgRkI,97
|
|
|
28
28
|
pynapse/evm/client.py,sha256=OZY3MLq49KjjxTx3w25xgwoX9fWyvLfq1amFsHfzoLQ,608
|
|
29
29
|
pynapse/filbeam/__init__.py,sha256=aY5abqgV5mJikOkn0IDNyjB8y9PsHwU8zWkUKL5dnGg,96
|
|
30
30
|
pynapse/filbeam/service.py,sha256=2QcAakeDxiaNahAwX4O6KiEuUP3abXq_qyuPwsXaFQM,1311
|
|
31
|
+
pynapse/integrations/__init__.py,sha256=cGYH_anpanboIpIOs1AOQKwMpN4cTMQNwvGeBmFPSwM,221
|
|
32
|
+
pynapse/integrations/langchain.py,sha256=eQJBjZOWF9e7XoCCaONMi2Y125rPirhpBXt-nHChbZc,6684
|
|
31
33
|
pynapse/payments/__init__.py,sha256=Hpwyec7OK8C1OVwrNgmxuH71pPzUBRsgwWXgZzKCt5c,302
|
|
32
34
|
pynapse/payments/service.py,sha256=DFLhMgeuM7AWgZSe5dWtGEqa1amYDujbFr366BmfAkI,32121
|
|
33
35
|
pynapse/pdp/__init__.py,sha256=cfS8u4nGQ7dKHZxy3fUCHSnwUTjkejNya9iGnOHCt9Q,490
|
|
@@ -58,7 +60,7 @@ pynapse/utils/metadata.py,sha256=-tEl9PAgPdBUhFqze0-ZRzn6_jIbiHTLDnlD3QM0FQ0,113
|
|
|
58
60
|
pynapse/utils/piece_url.py,sha256=md27_fxtcCyBvREBLNBJquJMj1V1gSdobfHe9x3RmhU,513
|
|
59
61
|
pynapse/warm_storage/__init__.py,sha256=WdUamV4veb7ZHyRWU12tQj8V5IVblbrgpNAyv5WSUE8,246
|
|
60
62
|
pynapse/warm_storage/service.py,sha256=eRZEDkN0257cVSs665cRQYqZUlL-BDAxfAFD6GY344E,22770
|
|
61
|
-
synapse_filecoin_sdk-0.
|
|
62
|
-
synapse_filecoin_sdk-0.
|
|
63
|
-
synapse_filecoin_sdk-0.
|
|
64
|
-
synapse_filecoin_sdk-0.
|
|
63
|
+
synapse_filecoin_sdk-0.2.0.dist-info/METADATA,sha256=EdcnJylO0DxRPKbzBjkRXyLQZbNo7AdGWADg_1By2Fo,3266
|
|
64
|
+
synapse_filecoin_sdk-0.2.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
65
|
+
synapse_filecoin_sdk-0.2.0.dist-info/licenses/LICENSE.md,sha256=AkqszG9dHKiuURbWTvtFVRX_X17biR28Tihp8Tt8xO0,12466
|
|
66
|
+
synapse_filecoin_sdk-0.2.0.dist-info/RECORD,,
|
|
File without changes
|
{synapse_filecoin_sdk-0.1.1.dist-info → synapse_filecoin_sdk-0.2.0.dist-info}/licenses/LICENSE.md
RENAMED
|
File without changes
|