.. aioipfs documentation master file, created by sphinx-quickstart on Mon Sep 3 00:02:10 2018. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. ======= aioipfs ======= *aioipfs* is an asynchronous Python client library for `kubo `_ (formerly called *go-ipfs*), which is the reference implementation of the `IPFS `_ (*Interplanetary Filesystem*) protocol. *aioipfs* uses the `aiohttp `_ library to access kubo's `RPC `_ endpoints. .. toctree:: :maxdepth: 2 :name: mastertoc api bohort .. module:: aioipfs .. currentmodule:: aioipfs Installation ============ You can use any Python version that supports `asyncio `_ and asynchronous generators (from Python version 3.6 to version 3.12). .. code-block:: shell pip install aioipfs Support for CAR (Content-Addressable aRchives) decoding (with the `ipfs-car-decoder package `_) can be enabled with the *car* extra: .. code-block:: shell pip install 'aioipfs[car]' If you want to use orjson_ to decode JSON messages: .. code-block:: shell pip install 'aioipfs[orjson]' To install the dependencies required by :ref:`bohort`, a REPL CLI tool to interact with kubo nodes: .. code-block:: shell pip install 'aioipfs[bohort]' Checkout the bohort documentation :doc:`here `. Async IPFS client ================= When creating a :class:`~aioipfs.AsyncIPFS` client instance it's recommended to specify the node's RPC API address with a multiaddr_:: import aioipfs client = aioipfs.AsyncIPFS(maddr='/ip4/127.0.0.1/tcp/5001') client = aioipfs.AsyncIPFS(maddr='/dns4/localhost/tcp/5001') The default constructor assumes that the kubo_ node you want to connect to is *localhost* on port *5001* (use the *host* and *port* keyword arguments to set different values):: client = aioipfs.AsyncIPFS() client = aioipfs.AsyncIPFS(host='10.0.12.3', port=5003) *HTTPS RPC*: if the node you're connecting to uses the *https* protocol to serve the RPC API, specify *https* in the multiaddr_, or force the URL scheme by passing *scheme*:: client = aioipfs.AsyncIPFS(maddr='/ip4/10.0.1.4/tcp/5001/https') client = aioipfs.AsyncIPFS(host='10.0.1.4', scheme='https') Maximum HTTP connections and read timeout parameters:: client = aioipfs.AsyncIPFS(host='localhost', port=5008, conns_max=20) client = aioipfs.AsyncIPFS(host='localhost', port=5008, read_timeout=30) RPC authentication credentials ------------------------------ Starting with version *0.25.0*, kubo supports limiting access to certain parts of the RPC API by requiring the client to provide credentials via the HTTP *Authorization* header, either with a simple *Basic Auth* login and password, or with a token. `kubo RPC Authorization documentation `_. If the kubo server requires authentication, you can pass the RPC authentication credentials via the constructor's *auth* keyword argument:: client = aioipfs.AsyncIPFS(auth=aioipfs.BasicAuth('john', 'password123')) client = aioipfs.AsyncIPFS(auth=aioipfs.BearerAuth('my-secret-token')) You can change the credentials at any time by setting the *auth* object attribute:: client.auth = aioipfs.BasicAuth('alice', 'anotherpass') client.auth = None A :class:`~aioipfs.exceptions.RPCAccessDenied` exception will be raised if you are forbidden to use a certain API or if your credentials are invalid. Async context manager --------------------- You can use an async context manager in your code:: async with aioipfs.AsyncIPFS() as client: async for reply in client.ping(peer_id): ... Closing ------- When finished you should always call :meth:`AsyncIPFS.close` on your client:: await client.close() Content-Addressable aRchives decoding support ============================================= CAR The Content Archive format is a way of packaging up content addressed data into archive files that can be easily stored and transferred. You can think of them like TAR files that are designed for storing collections of content addressed data. *Source*: `What is a Content Archive `_ Specs: `CAR Specs `_ If you've installed the *ipfs-car-decoder* package via the *car* extra, you can use various utility functions and APIs to decode the Content-Addressable aRchives generated by kubo, or to open .car files: - Use :func:`aioipfs.util.car_open` to open a .car archive file (this returns a `FileByteStream `_) - Use :func:`aioipfs.util.car_bytes` to get the raw bytes content from a CAR stream. The first argument is the CAR stream, the second argument must be the CID of a UnixFS file:: from pathlib import Path from aioipfs import util data = await util.car_bytes( util.car_open(Path('docs.car')), 'bafybeiawyahkjt4kzrzc3bjylqupniukbpnbvys7pt536c64gxg7onq36m' ) - Use the :meth:`apis.dag.DagAPI.export` coroutine to export a DAG to a .car file:: from pathlib import Path import aioipfs async with aioipfs.AsyncIPFS() as client: await client.dag.export( 'bafybeiawyahkjt4kzrzc3bjylqupniukbpnbvys7pt536c64gxg7onq36m', output_path=Path('output.car') ) - Use the :meth:`apis.dag.DagAPI.export_to_directory` coroutine to export a UnixFS DAG to a CAR and unpack it to a directory on the filesystem. Example:: from pathlib import Path import aioipfs async with aioipfs.AsyncIPFS() as client: await client.dag.export_to_directory( 'bafybeiawyahkjt4kzrzc3bjylqupniukbpnbvys7pt536c64gxg7onq36m', Path('car-contents') ) API sectioning ============== The kubo_ (formerly called *go-ipfs*) RPC HTTP API provides many endpoints which allow to access the different subsystems of the IPFS daemon. You can read the `RPC API specifications here `_. **Important**: The **aioipfs** client API closely follows kubo_'s RPC endpoints path hierarchy, as each subsystem has its own namespace/attribute inside the *AsyncIPFS* client object, for example: - *client.core* for the :class:`~api.CoreAPI` - *client.pin* for the :class:`~apis.pin.PinAPI` - *client.pin.remote* for the :class:`~apis.pin.PinRemoteAPI` - *client.files* for the :class:`~api.FilesAPI` - *client.pubsub* for the :class:`~apis.pubsub.PubSubAPI` etc ... All API functions will raise an :class:`~aioipfs.exceptions.APIError` (or a more specific exception) if there's an error raised during the request. Core API ======== .. attribute:: aioipfs.AsyncIPFS.core Gives access to the :class:`~api.CoreAPI` Adding files ------------- Add files to the IPFS repository with the :meth:`api.CoreAPI.add` async generator:: async for added in client.core.add('file1.txt', '/usr/local/src', recursive=True): print(added['Hash']) async for added in client.core.add(['one', 'two', 'three'], wrap_with_directory=True): ... cids = [entry['Hash'] async for entry in client.add(dir_path)] Entries yielded by the generator are as returned by the IPFS daemon, dictionaries with *Name*, *Hash* and *Size* keys. Since kubo *v0.16.0*, you can import a file and link the resulting object inside the MFS in the same RPC call, by using the *to_files* string argument, which should be the path in the MFS for the link:: async for added in client.core.add('file1.txt', to_files='/file1.txt'): print(added['Hash']) Ignoring files with .gitignore or .ipfsignore ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ *aioipfs* supports the use of `gitignore `_ files to specify which files should not be imported in IPFS. Use the *ignore_rules_path* keyword argument to indicate the name of the file (relative to the directory you're importing) containing the ignore rules:: async for added in client.core.add('directory', recursive=True, ignore_rules_path='.ipfsignore'): print(added['Hash']) Adding bytes ------------ Add some bytes with :meth:`api.CoreAPI.add_bytes`:: >>> entry = await client.core.add_bytes(b'ABCD') {'Name': 'QmZ655k2oftYnsocBxqTWzDer3GNui2XQTtcA4ZUbhpz5N', 'Hash': 'QmZ655k2oftYnsocBxqTWzDer3GNui2XQTtcA4ZUbhpz5N', 'Size': '12'} entry = await client.core.add_bytes('ABCD', to_files='/abcd') Adding string data ------------------ Add a UTF-8 string with :meth:`api.CoreAPI.add_str`:: entry = await client.core.add_str('ABCD') entry = await client.core.add_str('ABCD', to_files='/abcd') Getting IPFS objects -------------------- Download IPFS objects with :meth:`api.CoreAPI.get`:: await client.core.get('QmRGqvWK44oWu8re5whp43P2M7j5XEDLHmPB3wncYFmCNg') await client.core.get('QmRGqvWK44oWu8re5whp43P2M7j5XEDLHmPB3wncYFmCNg', dstdir='/tmp') Cat --- Use :meth:`api.CoreAPI.cat` to get an object's raw data:: bytes = await client.core.cat(cid) Listing a path or CID --------------------- Use :meth:`api.CoreAPI.ls` for listing:: listing = await client.core.ls(path) Node information ---------------- Get IPFS node information:: info = await client.core.id() Block API ========= .. attribute:: aioipfs.AsyncIPFS.block Gives access to the :class:`~api.BlockAPI` Bitswap API =========== .. attribute:: aioipfs.AsyncIPFS.bitswap Gives access to the :class:`~api.BitswapAPI` Bootstrap API ============= .. attribute:: aioipfs.AsyncIPFS.bootstrap Gives access to the :class:`~api.BootstrapAPI` Config API ========== .. attribute:: aioipfs.AsyncIPFS.config Gives access to the :class:`~api.ConfigAPI` CID API ======= .. attribute:: aioipfs.AsyncIPFS.cid Gives access to the :class:`~api.CidAPI` DAG API ======= .. attribute:: aioipfs.AsyncIPFS.dag Gives access to the :class:`~apis.dag.DagAPI` DHT API ======= .. attribute:: aioipfs.AsyncIPFS.dht Gives access to the :class:`~api.DhtAPI` Diag API ======== .. attribute:: aioipfs.AsyncIPFS.diag Gives access to the :class:`~api.DiagAPI` File API ======== .. attribute:: aioipfs.AsyncIPFS.file Gives access to the :class:`~api.FileAPI` Files API ========= .. attribute:: aioipfs.AsyncIPFS.files Gives access to the :class:`~api.FilesAPI` Filestore API ============= .. attribute:: aioipfs.AsyncIPFS.filestore Gives access to the :class:`~api.FilestoreAPI` Key API ======= .. attribute:: aioipfs.AsyncIPFS.key Gives access to the :class:`~api.KeyAPI` Log API ======= .. attribute:: aioipfs.AsyncIPFS.log Gives access to the :class:`~api.LogAPI` Access the IPFS event log with:: import pprint async for msg in client.log.tail(): print(pprint.pprint(msg)) Multibase API ============= .. attribute:: aioipfs.AsyncIPFS.multibase Gives access to the :class:`~apis.multibase.MultibaseAPI` Name API ======== .. attribute:: aioipfs.AsyncIPFS.name Gives access to the :class:`~api.NameAPI` Object API ========== .. attribute:: aioipfs.AsyncIPFS.object Gives access to the :class:`~api.ObjectAPI` P2P API ======= .. attribute:: aioipfs.AsyncIPFS.p2p Gives access to the :class:`~apis.p2p.P2PAPI` There's an API to easily dial a P2P service through an async context manager:: async with client.p2p.dial_service( '12D3KooWRd9Pt1Fri5F4W32uhGm8fBG4pvxEiFwgMru85zmajxcd', '/x/myservice') as ctx: if ctx.failed: # Dialing failed raise Exception('....') # The multiaddr is available as 'ctx.maddr' print(f'Multiaddr': {ctx.maddr}') # The host/port can be retrieved via maddr_host and maddr_port print(f'Host: {ctx.maddr_host}, port: {ctx.maddr_port}') Example of dialing a remote http service (using *ctx.httpUrl()*):: async with client.p2p.dial_service( '12D3KooWRd9Pt1Fri5F4W32uhGm8fBG4pvxEiFwgMru85zmajxcd', '/x/http1') as ctx: async with aiohttp.ClientSession() as sess: async with sess.get(ctx.httpUrl('/')) as resp: print(await resp.read()) Pin API ======= .. attribute:: aioipfs.AsyncIPFS.pin Gives access to the :class:`~apis.pin.PinAPI` Pinning a CID or an IPFS path:: async for pinned in client.pin.add(cid): print('Pin progress', pinned['Progress']) Listing the pinned objects:: pinned = await client.pin.ls() Unpin with:: await client.pin.rm(path) Pin remote API ============== .. attribute:: aioipfs.AsyncIPFS.pin.remote Gives access to the :class:`~apis.pin.PinRemoteAPI` Pubsub API ========== .. attribute:: aioipfs.AsyncIPFS.pubsub Gives access to the :class:`~apis.pubsub.PubSubAPI` Refs API ======== .. attribute:: aioipfs.AsyncIPFS.refs Gives access to the :class:`~api.RefsAPI` Repo API ======== .. attribute:: aioipfs.AsyncIPFS.repo Gives access to the :class:`~api.RepoAPI` Routing API =========== .. attribute:: aioipfs.AsyncIPFS.routing Gives access to the :class:`~api.RoutingAPI` Swarm API ========= .. attribute:: aioipfs.AsyncIPFS.swarm Gives access to the :class:`~apis.swarm.SwarmAPI` Swarm Peering API ================= .. attribute:: aioipfs.AsyncIPFS.swarm.peering Gives access to the :class:`~apis.swarm.SwarmPeeringAPI` TAR API ======= .. attribute:: aioipfs.AsyncIPFS.tar Gives access to the :class:`~api.TarAPI` Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` .. _multiaddr: https://multiformats.io/multiaddr/ .. _kubo: https://github.com/ipfs/kubo .. _orjson: https://github.com/ijl/orjson