88import aioipfs
99from configmanager import Config
1010
11- from aleph .services .ipfs .common import make_ipfs_client
11+ from aleph .services .ipfs .common import make_ipfs_p2p_client , make_ipfs_pinning_client
1212from aleph .services .utils import get_IP
1313from aleph .types .message_status import FileUnavailable
1414from aleph .utils import run_in_executor
1919
2020
2121class IpfsService :
22- def __init__ (self , ipfs_client : aioipfs .AsyncIPFS ):
23- self .ipfs_client = ipfs_client
22+ def __init__ (
23+ self ,
24+ ipfs_client : aioipfs .AsyncIPFS ,
25+ pinning_client : Optional [aioipfs .AsyncIPFS ] = None ,
26+ ):
27+ self .ipfs_client = ipfs_client # For P2P operations
28+ self .pinning_client = pinning_client or ipfs_client # For pinning operations
2429
2530 @classmethod
2631 def new (cls , config : Config ) -> Self :
27- ipfs_client = make_ipfs_client (config )
28- return cls (ipfs_client = ipfs_client )
32+ # Create P2P client (for content retrieval, pubsub)
33+ p2p_client = make_ipfs_p2p_client (config )
34+
35+ # Create separate pinning client if configured differently
36+ if _should_use_separate_pinning_client (config ):
37+ LOGGER .info ("Using separate IPFS client for pinning operations" )
38+ pinning_client = make_ipfs_pinning_client (config )
39+ else :
40+ pinning_client = p2p_client
41+
42+ return cls (ipfs_client = p2p_client , pinning_client = pinning_client )
2943
3044 async def __aenter__ (self ):
3145 return self
3246
3347 async def close (self ):
3448 await self .ipfs_client .close ()
49+ # Only close pinning client if it's different from main client
50+ if self .pinning_client != self .ipfs_client :
51+ await self .pinning_client .close ()
3552
3653 async def __aexit__ (self , exc_type , exc_val , exc_tb ):
3754 await self .close ()
@@ -183,11 +200,11 @@ async def get_json(self, hash, timeout=1, tries=1):
183200 return result
184201
185202 async def add_json (self , value : bytes ) -> str :
186- result = self .ipfs_client .add_json (value )
203+ result = self .pinning_client .add_json (value )
187204 return result ["Hash" ]
188205
189206 async def add_bytes (self , value : bytes , cid_version : int = 0 ) -> str :
190- result = await self .ipfs_client .add_bytes (value , cid_version = cid_version )
207+ result = await self .pinning_client .add_bytes (value , cid_version = cid_version )
191208 return result ["Hash" ]
192209
193210 async def _pin_add (self , cid : str , timeout : int = 30 ):
@@ -201,7 +218,8 @@ async def _pin_add(self, cid: str, timeout: int = 30):
201218 tick_timeout = timeout * 2
202219 last_progress = None
203220
204- async for status in self .ipfs_client .pin .add (cid ):
221+ # Use pinning client instead of main client
222+ async for status in self .pinning_client .pin .add (cid ):
205223 # If the Pins key appears, the file is pinned.
206224 if "Pins" in status :
207225 break
@@ -235,15 +253,13 @@ async def pin_add(self, cid: str, timeout: int = 30, tries: int = 1):
235253 break
236254
237255 async def add_file (self , file_content : bytes ):
238- url = f"{ self .ipfs_client .api_url } add"
256+ """
257+ Add a file to IPFS using bytes as data.
239258
240- async with aiohttp .ClientSession () as session :
241- data = aiohttp .FormData ()
242- data .add_field ("path" , file_content )
243-
244- resp = await session .post (url , data = data )
245- resp .raise_for_status ()
246- return await resp .json ()
259+ This is a backward-compatible wrapper around add_bytes().
260+ Uses the pinning client for write operations.
261+ """
262+ return await self .add_bytes (file_content )
247263
248264 async def sub (self , topic : str ):
249265 ipfs_client = self .ipfs_client
@@ -269,3 +285,23 @@ async def pub(self, topic: str, message: Union[str, bytes]):
269285
270286 ipfs_client = self .ipfs_client
271287 await ipfs_client .pubsub .pub (topic , message_str )
288+
289+
290+ def _should_use_separate_pinning_client (config : Config ) -> bool :
291+ """
292+ Determine if we should use a separate IPFS client for pinning operations.
293+ Returns True if pinning configuration is different from main IPFS configuration.
294+ """
295+ if not hasattr (config .ipfs , "pinning" ):
296+ return False
297+
298+ # Check if pinning host/port are specifically configured and different
299+ pinning_host = config .ipfs .pinning .host .value
300+ pinning_port = config .ipfs .pinning .port .value
301+
302+ if pinning_host and pinning_port :
303+ main_host = config .ipfs .host .value
304+ main_port = config .ipfs .port .value
305+ return (pinning_host != main_host ) or (pinning_port != main_port )
306+
307+ return False
0 commit comments