Skip to content

Commit

Permalink
Merge pull request #32 from lkluft/ipns
Browse files Browse the repository at this point in the history
Add AsyncIPNSFileSystem
  • Loading branch information
d70-t committed Sep 12, 2024
2 parents 2abf718 + c58f756 commit f12843e
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 15 deletions.
4 changes: 2 additions & 2 deletions ipfsspec/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from .async_ipfs import AsyncIPFSFileSystem
from .async_ipfs import AsyncIPFSFileSystem, AsyncIPNSFileSystem

from ._version import get_versions
__version__ = get_versions()['version']
del get_versions

__all__ = ["__version__", "AsyncIPFSFileSystem"]
__all__ = ["__version__", "AsyncIPFSFileSystem", "AsyncIPNSFileSystem"]
31 changes: 18 additions & 13 deletions ipfsspec/async_ipfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@ def _raise_not_found_for_status(self, response, url):
class AsyncIPFSGateway(AsyncIPFSGatewayBase):
resolution = "path"

def __init__(self, url):
def __init__(self, url, protocol="ipfs"):
self.url = url
self.protocol = protocol

async def api_get(self, endpoint, session, **kwargs):
res = await session.get(self.url + "/api/v0/" + endpoint, params=kwargs, trace_request_ctx={'gateway': self.url})
Expand All @@ -106,7 +107,7 @@ async def api_post(self, endpoint, session, **kwargs):
async def _cid_req(self, method, path, headers=None, **kwargs):
headers = headers or {}
if self.resolution == "path":
res = await method(self.url + "/ipfs/" + path, trace_request_ctx={'gateway': self.url}, headers=headers, **kwargs)
res = await method("/".join((self.url, self.protocol, path)), trace_request_ctx={'gateway': self.url}, headers=headers, **kwargs)
elif self.resolution == "subdomain":
raise NotImplementedError("subdomain resolution is not yet implemented")
else:
Expand Down Expand Up @@ -145,17 +146,17 @@ async def get_client(**kwargs):
return aiohttp.ClientSession(**kwargs)


def gateway_from_file(gateway_path):
def gateway_from_file(gateway_path, protocol="ipfs"):
if gateway_path.exists():
with open(gateway_path) as gw_file:
ipfs_gateway = gw_file.readline().strip()
logger.debug("using IPFS gateway from %s: %s", gateway_path, ipfs_gateway)
return AsyncIPFSGateway(ipfs_gateway)
return AsyncIPFSGateway(ipfs_gateway, protocol=protocol)
return None


@lru_cache
def get_gateway():
def get_gateway(protocol="ipfs"):
"""
Get IPFS gateway according to IPIP-280
Expand All @@ -166,29 +167,29 @@ def get_gateway():
ipfs_gateway = os.environ.get("IPFS_GATEWAY", "")
if ipfs_gateway:
logger.debug("using IPFS gateway from IPFS_GATEWAY environment variable: %s", ipfs_gateway)
return AsyncIPFSGateway(ipfs_gateway)
return AsyncGateway(ipfs_gateway, protocol)

# internal configuration: accept IPFSSPEC_GATEWAYS for backwards compatibility
if ipfsspec_gateways := os.environ.get("IPFSSPEC_GATEWAYS", ""):
ipfs_gateway = ipfsspec_gateways.split()[0]
logger.debug("using IPFS gateway from IPFSSPEC_GATEWAYS environment variable: %s", ipfs_gateway)
warnings.warn("The IPFSSPEC_GATEWAYS environment variable is deprecated, please configure your IPFS Gateway according to IPIP-280, e.g. by using the IPFS_GATEWAY environment variable or using the ~/.ipfs/gateway file.", DeprecationWarning)
return AsyncIPFSGateway(ipfs_gateway)
return AsyncGateway(ipfs_gateway, protocol)

# check various well-known files for possible gateway configurations
if ipfs_path := os.environ.get("IPFS_PATH", ""):
if ipfs_gateway := gateway_from_file(Path(ipfs_path) / "gateway"):
if ipfs_gateway := gateway_from_file(Path(ipfs_path) / "gateway", protocol):
return ipfs_gateway

if home := os.environ.get("HOME", ""):
if ipfs_gateway := gateway_from_file(Path(home) / ".ipfs" / "gateway"):
if ipfs_gateway := gateway_from_file(Path(home) / ".ipfs" / "gateway", protocol):
return ipfs_gateway

if config_home := os.environ.get("XDG_CONFIG_HOME", ""):
if ipfs_gateway := gateway_from_file(Path(config_home) / "ipfs" / "gateway"):
if ipfs_gateway := gateway_from_file(Path(config_home) / "ipfs" / "gateway", protocol):
return ipfs_gateway

if ipfs_gateway := gateway_from_file(Path("/etc") / "ipfs" / "gateway"):
if ipfs_gateway := gateway_from_file(Path("/etc") / "ipfs" / "gateway", protocol):
return ipfs_gateway

system = platform.system()
Expand All @@ -213,7 +214,7 @@ def get_gateway():
candidates = []

for candidate in candidates:
if ipfs_gateway := gateway_from_file(candidate):
if ipfs_gateway := gateway_from_file(candidate, protocol):
return ipfs_gateway

# if we reach this point, no gateway is configured
Expand Down Expand Up @@ -249,7 +250,7 @@ def __init__(self, asynchronous=False, loop=None, client_kwargs=None, **storage_

@property
def gateway(self):
return get_gateway()
return get_gateway(self.protocol)

@staticmethod
def close_session(loop, session):
Expand Down Expand Up @@ -300,3 +301,7 @@ def open(self, path, mode="rb", block_size=None, cache_options=None, **kwargs):
def ukey(self, path):
"""returns the CID, which is by definition an unchanging identitifer"""
return self.info(path)["CID"]


class AsyncIPNSFileSystem(AsyncIPFSFileSystem):
protocol = "ipns"
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
entry_points={
'fsspec.specs': [
'ipfs=ipfsspec.AsyncIPFSFileSystem',
'ipns=ipfsspec.AsyncIPNSFileSystem',
],
},
)

0 comments on commit f12843e

Please sign in to comment.