From 938160fa134551481e8bdb2ace692f4a41948cc0 Mon Sep 17 00:00:00 2001 From: emendir <91378069+emendir@users.noreply.github.com> Date: Mon, 1 Nov 2021 14:41:38 +0100 Subject: [PATCH 01/10] Add files via upload Expanded the API to implement the "ipfs p2p forward", "ipfs p2p listen" and "ipfs p2p close" commands. --- ipfshttpclient/client/p2p.py | 100 +++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 ipfshttpclient/client/p2p.py diff --git a/ipfshttpclient/client/p2p.py b/ipfshttpclient/client/p2p.py new file mode 100644 index 00000000..9cadcb41 --- /dev/null +++ b/ipfshttpclient/client/p2p.py @@ -0,0 +1,100 @@ +import typing as ty + +from . import base + + +class Section(base.SectionBase): + @base.returns_no_item + def forward(self, protocol: str, peer_id: str, port: str, **kwargs: base.CommonArgs): + """Forward connections to libp2p service + + Forward connections made to to . + + .. code-block:: python + + # forwards connections made to 'port' to 'QmHash' + >>> client.p2p.forward('protocol', 'port', 'QmHash') + [] + + Parameters + ---------- + protocol + specifies the libp2p protocol name to use for libp2p connections and/or handlers. It must be prefixed with '/x/'. + port + Listening endpoint +PeerID + Target endpoint + + Returns + ------- + list + An empty list + """ + args = (protocol, peer_id, port) + return self._client.request('/p2p/forward', args, decoder='json', **kwargs) + + @base.returns_no_item + def listen(self, protocol: str, port: str, **kwargs: base.CommonArgs): + """Create libp2p service + + + .. code-block:: python + + Create libp2p service and forward IPFS connections to 'port' + >>> client.p2p.listen('protocol', 'port') + [] + + Parameters + ---------- + protocol + specifies the libp2p handler name. It must be prefixed with '/x/'. + port + Listener port to which to forward incoming connections + + + Returns + ------- + list + An empty list + """ + args = (protocol, port) + return self._client.request('/p2p/listen', args, decoder='json', **kwargs) + + # @base.returns_single_item(base.ResponseBase) + def close(self, all: bool = False, protocol: str = None, listenaddress: str = None, targetaddress: str = None, **kwargs: base.CommonArgs): + """Create libp2p service + + + .. code-block:: python + + Create libp2p service and forward IPFS connections to 'port' + >>> client.p2p.listen('protocol', 'port') + [] + + Parameters + ---------- + protocol + specifies the libp2p handler name. It must be prefixed with '/x/'. + port + Listener port to which to forward incoming connections + + + Returns + ------- + list + An empty list + """ + + opts = {} + if all is not None: + opts.update({"all": all}) + if protocol is not None: + opts.update({"protocol": str(protocol)}) + if listenaddress is not None: + opts.update({"listen-address": str(listenaddress)}) + if targetaddress is not None: + opts.update({"target-address": str(targetaddress)}) + + kwargs.setdefault("opts", {}).update(opts) + args = (all,) # if all is not None else () + return self._client.request('/p2p/close', decoder='json', **kwargs) From e22a17d910cc8757126fcc8059710e87fa9d41d1 Mon Sep 17 00:00:00 2001 From: emendir <91378069+emendir@users.noreply.github.com> Date: Mon, 1 Nov 2021 14:46:51 +0100 Subject: [PATCH 02/10] Update __init__.py Updated __init__ to recognise the new p2p module in the same folder. --- ipfshttpclient/client/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ipfshttpclient/client/__init__.py b/ipfshttpclient/client/__init__.py index ec9e525f..4cc92423 100644 --- a/ipfshttpclient/client/__init__.py +++ b/ipfshttpclient/client/__init__.py @@ -35,6 +35,7 @@ from . import miscellaneous from . import name from . import object +from . import p2p from . import pin from . import pubsub from . import repo @@ -330,4 +331,4 @@ def get_json(self, cid, **kwargs): object Deserialized IPFS JSON object value """ - return self.cat(cid, decoder='json', **kwargs) \ No newline at end of file + return self.cat(cid, decoder='json', **kwargs) From dad746b9b482f0b549c687b6ab8eaa818a350ef2 Mon Sep 17 00:00:00 2001 From: emendir <91378069+emendir@users.noreply.github.com> Date: Mon, 1 Nov 2021 15:11:52 +0100 Subject: [PATCH 03/10] Fixed bugfix after testing last commit. --- ipfshttpclient/client/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ipfshttpclient/client/__init__.py b/ipfshttpclient/client/__init__.py index 4cc92423..0ec46b52 100644 --- a/ipfshttpclient/client/__init__.py +++ b/ipfshttpclient/client/__init__.py @@ -186,6 +186,7 @@ def close(self): # Call this when you're done key = base.SectionProperty(key.Section) name = base.SectionProperty(name.Section) object = base.SectionProperty(object.Section) + p2p = base.SectionProperty(p2p.Section) pin = base.SectionProperty(pin.Section) pubsub = base.SectionProperty(pubsub.Section) repo = base.SectionProperty(repo.Section) From 33107a6b0f1e8c2fd4f7f2efa29bd6f10cd22c3e Mon Sep 17 00:00:00 2001 From: emendir <91378069+emendir@users.noreply.github.com> Date: Mon, 1 Nov 2021 15:34:36 +0100 Subject: [PATCH 04/10] Fixed docstrings. --- ipfshttpclient/client/p2p.py | 39 ++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/ipfshttpclient/client/p2p.py b/ipfshttpclient/client/p2p.py index 9cadcb41..61975dd0 100644 --- a/ipfshttpclient/client/p2p.py +++ b/ipfshttpclient/client/p2p.py @@ -8,41 +8,44 @@ class Section(base.SectionBase): def forward(self, protocol: str, peer_id: str, port: str, **kwargs: base.CommonArgs): """Forward connections to libp2p service - Forward connections made to to . + Forward connections made to the specified port to another IPFS node. .. code-block:: python - # forwards connections made to 'port' to 'QmHash' - >>> client.p2p.forward('protocol', 'port', 'QmHash') + # forwards connections made to port 8888 to 'QmHash' as protocol '/x/testproto' + >>> client.p2p.forward('/x/testproto', 'QmHash', 8888) [] Parameters ---------- protocol specifies the libp2p protocol name to use for libp2p connections and/or handlers. It must be prefixed with '/x/'. + PeerID + Target endpoint port Listening endpoint -PeerID - Target endpoint Returns ------- - list - An empty list + list + An empty list """ args = (protocol, peer_id, port) return self._client.request('/p2p/forward', args, decoder='json', **kwargs) @base.returns_no_item def listen(self, protocol: str, port: str, **kwargs: base.CommonArgs): - """Create libp2p service + """Create libp2p service to forward IPFS connections to port + + Creates a libp2p service that forwards IPFS connections to it + to the specified port on the local computer. .. code-block:: python - Create libp2p service and forward IPFS connections to 'port' - >>> client.p2p.listen('protocol', 'port') - [] + # listens for connections of protocol '/x/testproto' and forwards them to port 8888 + >>> client.p2p.listen('/x/testproto', 8888) + [] Parameters ---------- @@ -54,22 +57,23 @@ def listen(self, protocol: str, port: str, **kwargs: base.CommonArgs): Returns ------- - list - An empty list + list + An empty list """ args = (protocol, port) return self._client.request('/p2p/listen', args, decoder='json', **kwargs) # @base.returns_single_item(base.ResponseBase) def close(self, all: bool = False, protocol: str = None, listenaddress: str = None, targetaddress: str = None, **kwargs: base.CommonArgs): - """Create libp2p service + """Stop listening for new connections to forward. + Stops all forwarding and listening libp2p services that match the input arguments. .. code-block:: python - Create libp2p service and forward IPFS connections to 'port' - >>> client.p2p.listen('protocol', 'port') - [] + # Close listening and forwarding connections of protocol '/x/testproto' and port 8888. + >>> client.p2p.close(protocol='/x/testproto', port='8888') + [] Parameters ---------- @@ -98,3 +102,4 @@ def close(self, all: bool = False, protocol: str = None, listenaddress: str = No kwargs.setdefault("opts", {}).update(opts) args = (all,) # if all is not None else () return self._client.request('/p2p/close', decoder='json', **kwargs) + From 6b9d26e6a013513f0f63a28c5d155e273cc3ef16 Mon Sep 17 00:00:00 2001 From: emendir <91378069+emendir@users.noreply.github.com> Date: Mon, 1 Nov 2021 15:44:07 +0100 Subject: [PATCH 05/10] Customised ReadMe to my fork. --- README.md | 48 ++---------------------------------------------- 1 file changed, 2 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 80b6f55f..95a1d8d6 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ Check out [the HTTP Client reference](https://ipfs.io/ipns/12D3KooWEqnTdgqHnkkwarSrJjeMP2ZJiADWLYADaNvUb6SQNyPF/docs/) for the full command reference. +A fork of ipfs-shipyard/py-ipfs-http-client, the official ipfshttpclient python module, which I have expanded to access IPFS's LibP2PStreamMounting feature. + **Note**: The `ipfsapi` PIP package and Python module have both been renamed to `ipfshttpclient`! See the [relevant section of the CHANGELOG](CHANGELOG.md#py-ipfs-http-client-0411-13052019) for details. There is also a `ipfsApi` library from which this library originated that is completely unmaintained and does not work with any recent go-IPFS version. @@ -222,49 +224,3 @@ and running `flit install --pth-file` from the repository root. Please see the next section for how to run tests and contribute code back into the project. - - -### Pull requests - -Pull requests are welcome. Before submitting a new pull request, please -make sure that your code passes both the -[code formatting](https://www.python.org/dev/peps/pep-0008/) -(PEP-8 with tab indentation) and -[typing](https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html) -(PEP-484 using mypy) checks: - - $ tox -e styleck -e typeck - -As well as the unit tests: - - $ tox -e py3 -e py3-httpx - -If you are unsure, don't hesitate to just submit your code, and a human will -take a look. 🙂 - -If you can, Please make sure to include new unit tests for new features or -changes in behavior. We aim to bring coverage to 100% at some point. - -#### Installing the pre-commit Hook - -You can arrange for the code style and typing tests to be run automatically -before each commit by installing the GIT `pre-commit` hook: - - $ ./tools/pre-commit --install - -### Chat with Us (IRC/Matrix) - -You can find us on [#py-ipfs on chat.freenode.org](http://webchat.freenode.net/?channels=%23py-ipfs) -or in our [Matrix chat room](https://matrix.to/#/#py-ipfs:ninetailed.ninja?via=ninetailed.ninja&via=librem.one). -Join us if you have any suggestions, questions or if you just want to discuss -IPFS and Python in general. - -Please note that the channel is not monitored all the time and hence you may -only receive a reply to your message later that day. Using Matrix makes it -easier to stay connected in the background, so please prefer the Matrix option -or use an IRC bouncer. - -## License - -This code is distributed under the terms of the [MIT license](https://opensource.org/licenses/MIT). Details can be found in the file -[LICENSE](LICENSE) in this repository. From 3a6a03e3b2e9ec0f61f3bfece0189fda9eafa863 Mon Sep 17 00:00:00 2001 From: emendir <91378069+emendir@users.noreply.github.com> Date: Mon, 1 Nov 2021 15:44:46 +0100 Subject: [PATCH 06/10] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 95a1d8d6..3ab3a37b 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,9 @@ ![Python IPFS HTTP Client Library](https://ipfs.io/ipfs/QmQJ68PFMDdAsgCZvA1UVzzn18asVcf7HVvCDgpjiSCAse) -Check out [the HTTP Client reference](https://ipfs.io/ipns/12D3KooWEqnTdgqHnkkwarSrJjeMP2ZJiADWLYADaNvUb6SQNyPF/docs/) for the full command reference. +#A fork of ipfs-shipyard/py-ipfs-http-client, the official ipfshttpclient python module, which I have expanded to access IPFS's LibP2PStreamMounting feature. -A fork of ipfs-shipyard/py-ipfs-http-client, the official ipfshttpclient python module, which I have expanded to access IPFS's LibP2PStreamMounting feature. +Check out [the HTTP Client reference](https://ipfs.io/ipns/12D3KooWEqnTdgqHnkkwarSrJjeMP2ZJiADWLYADaNvUb6SQNyPF/docs/) for the full command reference. **Note**: The `ipfsapi` PIP package and Python module have both been renamed to `ipfshttpclient`! See the [relevant section of the CHANGELOG](CHANGELOG.md#py-ipfs-http-client-0411-13052019) for details. There is also a `ipfsApi` library from which this library originated that is completely From d0d17407e6ecbf79565d9091b8d65c6d3f7cc825 Mon Sep 17 00:00:00 2001 From: emendir <91378069+emendir@users.noreply.github.com> Date: Mon, 1 Nov 2021 15:45:05 +0100 Subject: [PATCH 07/10] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ab3a37b..abb3cc20 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ![Python IPFS HTTP Client Library](https://ipfs.io/ipfs/QmQJ68PFMDdAsgCZvA1UVzzn18asVcf7HVvCDgpjiSCAse) -#A fork of ipfs-shipyard/py-ipfs-http-client, the official ipfshttpclient python module, which I have expanded to access IPFS's LibP2PStreamMounting feature. +# A fork of ipfs-shipyard/py-ipfs-http-client, the official ipfshttpclient python module, which I have expanded to access IPFS's LibP2PStreamMounting feature. Check out [the HTTP Client reference](https://ipfs.io/ipns/12D3KooWEqnTdgqHnkkwarSrJjeMP2ZJiADWLYADaNvUb6SQNyPF/docs/) for the full command reference. From 3938d916ca5745cab01f41199b357714a0d0ccb1 Mon Sep 17 00:00:00 2001 From: emendir <91378069+emendir@users.noreply.github.com> Date: Mon, 1 Nov 2021 15:46:01 +0100 Subject: [PATCH 08/10] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index abb3cc20..00d31974 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ![Python IPFS HTTP Client Library](https://ipfs.io/ipfs/QmQJ68PFMDdAsgCZvA1UVzzn18asVcf7HVvCDgpjiSCAse) -# A fork of ipfs-shipyard/py-ipfs-http-client, the official ipfshttpclient python module, which I have expanded to access IPFS's LibP2PStreamMounting feature. +# A fork of [ipfs-shipyard/py-ipfs-http-client](https://github.com/ipfs-shipyard/py-ipfs-http-client), the official ipfshttpclient python module, which I have expanded to access IPFS's LibP2PStreamMounting feature. Check out [the HTTP Client reference](https://ipfs.io/ipns/12D3KooWEqnTdgqHnkkwarSrJjeMP2ZJiADWLYADaNvUb6SQNyPF/docs/) for the full command reference. From 2c86a9419d7b875f669610922f77756045d86aaf Mon Sep 17 00:00:00 2001 From: emendir <91378069+emendir@users.noreply.github.com> Date: Mon, 1 Nov 2021 15:55:04 +0100 Subject: [PATCH 09/10] Undid changes to Readme for pull request. --- README.md | 236 ++++++++++++------------------------------------------ 1 file changed, 50 insertions(+), 186 deletions(-) diff --git a/README.md b/README.md index 00d31974..838d1878 100644 --- a/README.md +++ b/README.md @@ -1,226 +1,90 @@ -# py-ipfs-http-client -[![Made by the IPFS Community](https://img.shields.io/badge/made%20by-IPFS%20Community-blue.svg?style=flat-square)](https://docs.ipfs.io/community/) -[![IRC #py-ipfs on chat.freenode.net](https://img.shields.io/badge/freenode%20IRC-%23py--ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23py-ipfs) -[![Matrix #py-ipfs:ninetailed.ninja](https://img.shields.io/matrix/py-ipfs:ninetailed.ninja?color=blue&label=matrix%20chat&server_fqdn=matrix.ninetailed.ninja&style=flat-square)](https://matrix.to/#/#py-ipfs:ninetailed.ninja?via=matrix.ninetailed.ninja&via=librem.one) -[![Standard README Compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) -[![PyPI Package ipfshttpclient](https://img.shields.io/pypi/dm/ipfshttpclient.svg?style=flat-square)](https://pypi.python.org/pypi/ipfshttpclient) -[![Build Status](https://img.shields.io/travis/com/ipfs-shipyard/py-ipfs-http-client/master.svg?style=flat-square)](https://travis-ci.com/github/ipfs-shipyard/py-ipfs-http-client) +# Release -![Python IPFS HTTP Client Library](https://ipfs.io/ipfs/QmQJ68PFMDdAsgCZvA1UVzzn18asVcf7HVvCDgpjiSCAse) +The release process uses `flit` to build the package, `Sphinx` to generate documentation, +publishes the documentation to an IPFS server (obtaining an IPFS hash), and then links +the IPFS hash (which varies based on content) to a static IPNS name. -# A fork of [ipfs-shipyard/py-ipfs-http-client](https://github.com/ipfs-shipyard/py-ipfs-http-client), the official ipfshttpclient python module, which I have expanded to access IPFS's LibP2PStreamMounting feature. +The IPNS name requires a private key, which is controlled by the project owners and not +available to the public. -Check out [the HTTP Client reference](https://ipfs.io/ipns/12D3KooWEqnTdgqHnkkwarSrJjeMP2ZJiADWLYADaNvUb6SQNyPF/docs/) for the full command reference. +All steps can be completed up through but not including linking the IPFS hash to IPNS. -**Note**: The `ipfsapi` PIP package and Python module have both been renamed to `ipfshttpclient`! -See the [relevant section of the CHANGELOG](CHANGELOG.md#py-ipfs-http-client-0411-13052019) for details. There is also a `ipfsApi` library from which this library originated that is completely -unmaintained and does not work with any recent go-IPFS version. - -**Note**: This library occasionally has to change to stay compatible with the IPFS HTTP API. -Currently, this library is tested against [go-ipfs v0.8.0](https://github.com/ipfs/go-ipfs/releases/tag/v0.8.0). -We strive to support the last 5 releases of go-IPFS at any given time; go-IPFS v0.5.0 therefore -being to oldest supported version at this time. - -## Table of Contents - -- [Install](#install) -- [Usage](#usage) -- [Documentation](#documentation) - - [Migrating from 0.4.x to 0.6.0](#migrating-from-04x-to-060) -- [Featured Projects](#featured-projects) -- [Contributing](#contributing) - - [Easy Tasks](#easy-tasks) - - [Bug reports](#bug-reports) - - [Setting up a local development environment](#setting-up-a-local-development-environment) - - [Pull requests](#pull-requests) - - [Chat with Us (IRC/Matrix)](#chat-with-us-ircmatrix) -- [License](#license) - -## Install - -Install with pip: - -```sh -pip install ipfshttpclient -``` - -### Development install from Source - -```sh -# Clone the source repository -git clone https://github.com/ipfs/py-ipfs-http-client.git -cd py-ipfs-http-client - -# Link ipfs-api-client into your Python Path -flit install --pth-file -``` - -## Usage - -Basic use-case (requires a running instance of IPFS daemon): - -```py ->>> import ipfshttpclient ->>> client = ipfshttpclient.connect() # Connects to: /dns/localhost/tcp/5001/http ->>> res = client.add('test.txt') ->>> res -{'Hash': 'QmWxS5aNTFEc9XbMX1ASvLET1zrqEaTssqt33rVZQCQb22', 'Name': 'test.txt'} ->>> client.cat(res['Hash']) -'fdsafkljdskafjaksdjf\n' -``` - -*Please note*: You should specify the address for an IPFS *API server*, using the address of a *gateway* (such as the public `ipfs.io` one at `/dns/ipfs.io/tcp/443/https`) will only give you [extremely limited access](https://github.com/ipfs/go-ipfs/blob/master/docs/gateway.md#read-only-api) and may not work at all. If you are only interested in downloading IPFS content through public gateway servers then this library is unlikely of being of much help. - -For real-world scripts you can reuse TCP connections using a context manager or manually closing the session after use: - -```py -import ipfshttpclient - -# Share TCP connections using a context manager -with ipfshttpclient.connect() as client: - hash = client.add('test.txt')['Hash'] - print(client.stat(hash)) - -# Share TCP connections until the client session is closed -class SomeObject: - def __init__(self): - self._client = ipfshttpclient.connect(session=True) - - def do_something(self): - hash = self._client.add('test.txt')['Hash'] - print(self._client.stat(hash)) - def close(self): # Call this when your done - self._client.close() -``` +## Pre-Requisites -Administrative functions: +* On Debian +* Python 3.8+ (or typings will be incomplete) -```py ->>> client.id() -{'Addresses': ['/ip4/127.0.0.1/tcp/4001/ipfs/QmS2C4MjZsv2iP1UDMMLCYqJ4WeJw8n3vXx1VKxW1UbqHS', - '/ip6/::1/tcp/4001/ipfs/QmS2C4MjZsv2iP1UDMMLCYqJ4WeJw8n3vXx1VKxW1UbqHS'], - 'AgentVersion': 'go-ipfs/0.4.10', - 'ID': 'QmS2C4MjZsv2iP1UDMMLCYqJ4WeJw8n3vXx1VKxW1UbqHS', - 'ProtocolVersion': 'ipfs/0.1.0', - 'PublicKey': 'CAASpgIwgg ... 3FcjAgMBAAE='} -``` -Pass in API options: +## One-Time Setup -```py ->>> client.pin.ls(type='all') -{'Keys': {'QmNMELyizsfFdNZW3yKTi1SE2pErifwDTXx6vvQBfwcJbU': {'Count': 1, - 'Type': 'indirect'}, - 'QmNQ1h6o1xJARvYzwmySPsuv9L5XfzS4WTvJSTAWwYRSd8': {'Count': 1, - 'Type': 'indirect'}, - … -``` +Install the release tools into your virtual environment: -Add a directory and match against a filename pattern: + $ pip install -r tools/release/requirements.txt -```py ->>> client.add('photos', pattern='*.jpg') -[{'Hash': 'QmcqBstfu5AWpXUqbucwimmWdJbu89qqYmE3WXVktvaXhX', - 'Name': 'photos/photo1.jpg'}, - {'Hash': 'QmSbmgg7kYwkSNzGLvWELnw1KthvTAMszN5TNg3XQ799Fu', - 'Name': 'photos/photo2.jpg'}, - {'Hash': 'Qma6K85PJ8dN3qWjxgsDNaMjWjTNy8ygUWXH2kfoq9bVxH', - 'Name': 'photos/photo3.jpg'}] -``` +Source: [tools/release/requirements.txt](tools/release/requirements.txt) -Or add a directory recursively: -```py ->>> client.add('fake_dir', recursive=True) -[{'Hash': 'QmQcCtMgLVwvMQGu6mvsRYLjwqrZJcYtH4mboM9urWW9vX', - 'Name': 'fake_dir/fsdfgh'}, - {'Hash': 'QmNuvmuFeeWWpxjCQwLkHshr8iqhGLWXFzSGzafBeawTTZ', - 'Name': 'fake_dir/test2/llllg'}, - {'Hash': 'QmX1dd5DtkgoiYRKaPQPTCtXArUu4jEZ62rJBUcd5WhxAZ', - 'Name': 'fake_dir/test2'}, - {'Hash': 'Qmenzb5J4fR9c69BbpbBhPTSp2Snjthu2hKPWGPPJUHb9M', - 'Name': 'fake_dir'}] -``` +### The Go IPFS daemon -This module also contains some helper functions for adding strings and JSON to IPFS: +Yes, we use IPFS to host our documentation. In case you haven't already you can download it here: +https://ipfs.io/docs/install/ -```py ->>> lst = [1, 77, 'lol'] ->>> client.add_json(lst) -'QmQ4R5cCUYBWiJpNL7mFe4LDrwD6qBr5Re17BoRAY9VNpd' ->>> client.get_json(_) -[1, 77, 'lol'] -``` -Use an IPFS server with basic auth (replace username and password with real creds): +### A dedicated IPNS key for publishing -```py ->>> import ipfshttpclient ->>> client = ipfshttpclient.connect('/dns/ipfs-api.example.com/tcp/443/https', auth=("username", "password")) -``` +For publishing the documentation an IPNS key used only for this task should be +generated if there is no such key already: -Pass custom headers to the IPFS daemon with each request: -```py ->>> import ipfshttpclient ->>> headers = {"CustomHeader": "foobar"} ->>> client = ipfshttpclient.connect('/dns/ipfs-api.example.com/tcp/443/https', headers=headers) -``` +`ipfs key gen --type ed25519 ipfs-http-client` -Connect to the IPFS daemon using a Unix domain socket (plain HTTP only): -```py ->>> import ipfshttpclient ->>> client = ipfshttpclient.connect("/unix/run/ipfs/ipfs.sock") -``` +This key will need to be copied to all other servers hosting the IPNS link. +Without the private key, other servers can host the IPFS files, but not the IPNS link. +At the time of writing the officially used key is: *12D3KooWEqnTdgqHnkkwarSrJjeMP2ZJiADWLYADaNvUb6SQNyPF* -## Documentation +# Steps -Documentation (currently mostly API documentation unfortunately) is available on IPFS: +## Update the source code -https://ipfs.io/ipns/12D3KooWEqnTdgqHnkkwarSrJjeMP2ZJiADWLYADaNvUb6SQNyPF/docs/ + 1. Make a GIT commit + * Incrementing the version number in `ipfshttpclient/version.py` + * Completing the currently open `CHANGELOG.md` entry -The `ipfs` [command-line Client documentation](https://ipfs.io/docs/commands/) may also be useful in some cases. + `git commit -m "Release version 0.X.Y" ipfshttpclient/version.py CHANGELOG.md` -### Migrating from `0.4.x` to `0.6.0` + 2. After the change is merged into master, pull master -Please see the CHANGELOG for [the minor breaking changes between these releases](CHANGELOG.md#py-ipfs-http-client-060-30062020). + 3. Tag the GIT commit with the version number using an annotated and signed tag: -## Featured Projects + `git tag --sign -m "Release version 0.X.Y" 0.X.Y` -Projects that currently use py-ipfs-http-client. If your project isn't here, feel free to submit a PR to add it! + 4. Push the new tag -- [InterPlanetary Wayback](https://github.com/oduwsdl/ipwb) interfaces web archive ([WARC](https://www.iso.org/standard/44717.html)) files for distributed indexing and replay using IPFS. -## Contributing +## Upload the new version to PyPI -### Easy Tasks +Run: -Over time many smaller day-to-day tasks have piled up (mostly supporting some -newer APIs). If want to help out without getting too involved picking up one -of tasks of our [help wanted issue list](https://github.com/ipfs-shipyard/py-ipfs-http-client/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) -would go a long way towards making this library more feature-complete. 👍 + $ flit build && flit publish -### Bug reports +## Re-generate and publish the documentation -You can submit bug reports using the -[GitHub issue tracker](https://github.com/ipfs/py-ipfs-http-client/issues). +Run: -### Setting up a local development environment + $ python docs/publish.py ipns-key-id - 1. Follow the instructions in the IPFS documentation to install go-IPFS into your `${PATH}`: - https://docs.ipfs.io/install/command-line/ - 2. Follow the instructions in the (Python) tox documentation to install the `tox` Python environment runner: - https://tox.readthedocs.io/en/latest/install.html - 3. Clone the GIT repository if you haven't already: - `git clone https://github.com/ipfs-shipyard/py-ipfs-http-client.git` +The command will also print a commandline that may be used to mirror the generated +documentation on systems other then the current one. -If you want to you can also make your local development version of -*py-ipfs-http-client* available to your Python environment by -[installing `flit`](https://flit.readthedocs.io/en/latest/#install) -and running `flit install --pth-file` from the repository root. +If you don't have the IPNS private key, you can still exercise the documentation +generation and publish process: -Please see the next section for how to run tests and contribute code -back into the project. + $ python docs/publish.py + +If you are publishing to an IPFS server that is remote, and protected by an HTTP reverse proxy +with TLS and basic authentication, run this instead: + + $ PY_IPFS_HTTP_CLIENT_DEFAULT_ADDR=/dns/yourserver.tld/tcp/5001/https PY_IPFS_HTTP_CLIENT_DEFAULT_USERNAME=basicauthuser PY_IPFS_HTTP_CLIENT_DEFAULT_PASSWORD=basicauthpassword python publish.py ipns-key-id From 2d7c113a14841295059e098836ab29f8cadc6b88 Mon Sep 17 00:00:00 2001 From: emendir <91378069+emendir@users.noreply.github.com> Date: Mon, 1 Nov 2021 15:56:30 +0100 Subject: [PATCH 10/10] Undid changes to ReadMe for pull request --- README.md | 276 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 228 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 838d1878..80b6f55f 100644 --- a/README.md +++ b/README.md @@ -1,90 +1,270 @@ +# py-ipfs-http-client -# Release +[![Made by the IPFS Community](https://img.shields.io/badge/made%20by-IPFS%20Community-blue.svg?style=flat-square)](https://docs.ipfs.io/community/) +[![IRC #py-ipfs on chat.freenode.net](https://img.shields.io/badge/freenode%20IRC-%23py--ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23py-ipfs) +[![Matrix #py-ipfs:ninetailed.ninja](https://img.shields.io/matrix/py-ipfs:ninetailed.ninja?color=blue&label=matrix%20chat&server_fqdn=matrix.ninetailed.ninja&style=flat-square)](https://matrix.to/#/#py-ipfs:ninetailed.ninja?via=matrix.ninetailed.ninja&via=librem.one) +[![Standard README Compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) +[![PyPI Package ipfshttpclient](https://img.shields.io/pypi/dm/ipfshttpclient.svg?style=flat-square)](https://pypi.python.org/pypi/ipfshttpclient) +[![Build Status](https://img.shields.io/travis/com/ipfs-shipyard/py-ipfs-http-client/master.svg?style=flat-square)](https://travis-ci.com/github/ipfs-shipyard/py-ipfs-http-client) -The release process uses `flit` to build the package, `Sphinx` to generate documentation, -publishes the documentation to an IPFS server (obtaining an IPFS hash), and then links -the IPFS hash (which varies based on content) to a static IPNS name. +![Python IPFS HTTP Client Library](https://ipfs.io/ipfs/QmQJ68PFMDdAsgCZvA1UVzzn18asVcf7HVvCDgpjiSCAse) -The IPNS name requires a private key, which is controlled by the project owners and not -available to the public. +Check out [the HTTP Client reference](https://ipfs.io/ipns/12D3KooWEqnTdgqHnkkwarSrJjeMP2ZJiADWLYADaNvUb6SQNyPF/docs/) for the full command reference. + +**Note**: The `ipfsapi` PIP package and Python module have both been renamed to `ipfshttpclient`! +See the [relevant section of the CHANGELOG](CHANGELOG.md#py-ipfs-http-client-0411-13052019) for details. There is also a `ipfsApi` library from which this library originated that is completely +unmaintained and does not work with any recent go-IPFS version. + +**Note**: This library occasionally has to change to stay compatible with the IPFS HTTP API. +Currently, this library is tested against [go-ipfs v0.8.0](https://github.com/ipfs/go-ipfs/releases/tag/v0.8.0). +We strive to support the last 5 releases of go-IPFS at any given time; go-IPFS v0.5.0 therefore +being to oldest supported version at this time. + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Documentation](#documentation) + - [Migrating from 0.4.x to 0.6.0](#migrating-from-04x-to-060) +- [Featured Projects](#featured-projects) +- [Contributing](#contributing) + - [Easy Tasks](#easy-tasks) + - [Bug reports](#bug-reports) + - [Setting up a local development environment](#setting-up-a-local-development-environment) + - [Pull requests](#pull-requests) + - [Chat with Us (IRC/Matrix)](#chat-with-us-ircmatrix) +- [License](#license) + +## Install + +Install with pip: + +```sh +pip install ipfshttpclient +``` + +### Development install from Source + +```sh +# Clone the source repository +git clone https://github.com/ipfs/py-ipfs-http-client.git +cd py-ipfs-http-client + +# Link ipfs-api-client into your Python Path +flit install --pth-file +``` + +## Usage + +Basic use-case (requires a running instance of IPFS daemon): + +```py +>>> import ipfshttpclient +>>> client = ipfshttpclient.connect() # Connects to: /dns/localhost/tcp/5001/http +>>> res = client.add('test.txt') +>>> res +{'Hash': 'QmWxS5aNTFEc9XbMX1ASvLET1zrqEaTssqt33rVZQCQb22', 'Name': 'test.txt'} +>>> client.cat(res['Hash']) +'fdsafkljdskafjaksdjf\n' +``` + +*Please note*: You should specify the address for an IPFS *API server*, using the address of a *gateway* (such as the public `ipfs.io` one at `/dns/ipfs.io/tcp/443/https`) will only give you [extremely limited access](https://github.com/ipfs/go-ipfs/blob/master/docs/gateway.md#read-only-api) and may not work at all. If you are only interested in downloading IPFS content through public gateway servers then this library is unlikely of being of much help. + +For real-world scripts you can reuse TCP connections using a context manager or manually closing the session after use: + +```py +import ipfshttpclient + +# Share TCP connections using a context manager +with ipfshttpclient.connect() as client: + hash = client.add('test.txt')['Hash'] + print(client.stat(hash)) + +# Share TCP connections until the client session is closed +class SomeObject: + def __init__(self): + self._client = ipfshttpclient.connect(session=True) + + def do_something(self): + hash = self._client.add('test.txt')['Hash'] + print(self._client.stat(hash)) -All steps can be completed up through but not including linking the IPFS hash to IPNS. + def close(self): # Call this when your done + self._client.close() +``` +Administrative functions: -## Pre-Requisites +```py +>>> client.id() +{'Addresses': ['/ip4/127.0.0.1/tcp/4001/ipfs/QmS2C4MjZsv2iP1UDMMLCYqJ4WeJw8n3vXx1VKxW1UbqHS', + '/ip6/::1/tcp/4001/ipfs/QmS2C4MjZsv2iP1UDMMLCYqJ4WeJw8n3vXx1VKxW1UbqHS'], + 'AgentVersion': 'go-ipfs/0.4.10', + 'ID': 'QmS2C4MjZsv2iP1UDMMLCYqJ4WeJw8n3vXx1VKxW1UbqHS', + 'ProtocolVersion': 'ipfs/0.1.0', + 'PublicKey': 'CAASpgIwgg ... 3FcjAgMBAAE='} +``` -* On Debian -* Python 3.8+ (or typings will be incomplete) +Pass in API options: +```py +>>> client.pin.ls(type='all') +{'Keys': {'QmNMELyizsfFdNZW3yKTi1SE2pErifwDTXx6vvQBfwcJbU': {'Count': 1, + 'Type': 'indirect'}, + 'QmNQ1h6o1xJARvYzwmySPsuv9L5XfzS4WTvJSTAWwYRSd8': {'Count': 1, + 'Type': 'indirect'}, + … +``` -## One-Time Setup +Add a directory and match against a filename pattern: -Install the release tools into your virtual environment: +```py +>>> client.add('photos', pattern='*.jpg') +[{'Hash': 'QmcqBstfu5AWpXUqbucwimmWdJbu89qqYmE3WXVktvaXhX', + 'Name': 'photos/photo1.jpg'}, + {'Hash': 'QmSbmgg7kYwkSNzGLvWELnw1KthvTAMszN5TNg3XQ799Fu', + 'Name': 'photos/photo2.jpg'}, + {'Hash': 'Qma6K85PJ8dN3qWjxgsDNaMjWjTNy8ygUWXH2kfoq9bVxH', + 'Name': 'photos/photo3.jpg'}] +``` - $ pip install -r tools/release/requirements.txt +Or add a directory recursively: -Source: [tools/release/requirements.txt](tools/release/requirements.txt) +```py +>>> client.add('fake_dir', recursive=True) +[{'Hash': 'QmQcCtMgLVwvMQGu6mvsRYLjwqrZJcYtH4mboM9urWW9vX', + 'Name': 'fake_dir/fsdfgh'}, + {'Hash': 'QmNuvmuFeeWWpxjCQwLkHshr8iqhGLWXFzSGzafBeawTTZ', + 'Name': 'fake_dir/test2/llllg'}, + {'Hash': 'QmX1dd5DtkgoiYRKaPQPTCtXArUu4jEZ62rJBUcd5WhxAZ', + 'Name': 'fake_dir/test2'}, + {'Hash': 'Qmenzb5J4fR9c69BbpbBhPTSp2Snjthu2hKPWGPPJUHb9M', + 'Name': 'fake_dir'}] +``` +This module also contains some helper functions for adding strings and JSON to IPFS: -### The Go IPFS daemon +```py +>>> lst = [1, 77, 'lol'] +>>> client.add_json(lst) +'QmQ4R5cCUYBWiJpNL7mFe4LDrwD6qBr5Re17BoRAY9VNpd' +>>> client.get_json(_) +[1, 77, 'lol'] +``` -Yes, we use IPFS to host our documentation. In case you haven't already you can download it here: -https://ipfs.io/docs/install/ +Use an IPFS server with basic auth (replace username and password with real creds): +```py +>>> import ipfshttpclient +>>> client = ipfshttpclient.connect('/dns/ipfs-api.example.com/tcp/443/https', auth=("username", "password")) +``` -### A dedicated IPNS key for publishing +Pass custom headers to the IPFS daemon with each request: +```py +>>> import ipfshttpclient +>>> headers = {"CustomHeader": "foobar"} +>>> client = ipfshttpclient.connect('/dns/ipfs-api.example.com/tcp/443/https', headers=headers) +``` -For publishing the documentation an IPNS key used only for this task should be -generated if there is no such key already: +Connect to the IPFS daemon using a Unix domain socket (plain HTTP only): +```py +>>> import ipfshttpclient +>>> client = ipfshttpclient.connect("/unix/run/ipfs/ipfs.sock") +``` -`ipfs key gen --type ed25519 ipfs-http-client` -This key will need to be copied to all other servers hosting the IPNS link. -Without the private key, other servers can host the IPFS files, but not the IPNS link. -At the time of writing the officially used key is: *12D3KooWEqnTdgqHnkkwarSrJjeMP2ZJiADWLYADaNvUb6SQNyPF* +## Documentation +Documentation (currently mostly API documentation unfortunately) is available on IPFS: -# Steps +https://ipfs.io/ipns/12D3KooWEqnTdgqHnkkwarSrJjeMP2ZJiADWLYADaNvUb6SQNyPF/docs/ -## Update the source code +The `ipfs` [command-line Client documentation](https://ipfs.io/docs/commands/) may also be useful in some cases. - 1. Make a GIT commit - * Incrementing the version number in `ipfshttpclient/version.py` - * Completing the currently open `CHANGELOG.md` entry +### Migrating from `0.4.x` to `0.6.0` - `git commit -m "Release version 0.X.Y" ipfshttpclient/version.py CHANGELOG.md` +Please see the CHANGELOG for [the minor breaking changes between these releases](CHANGELOG.md#py-ipfs-http-client-060-30062020). - 2. After the change is merged into master, pull master +## Featured Projects - 3. Tag the GIT commit with the version number using an annotated and signed tag: +Projects that currently use py-ipfs-http-client. If your project isn't here, feel free to submit a PR to add it! - `git tag --sign -m "Release version 0.X.Y" 0.X.Y` +- [InterPlanetary Wayback](https://github.com/oduwsdl/ipwb) interfaces web archive ([WARC](https://www.iso.org/standard/44717.html)) files for distributed indexing and replay using IPFS. - 4. Push the new tag +## Contributing +### Easy Tasks -## Upload the new version to PyPI +Over time many smaller day-to-day tasks have piled up (mostly supporting some +newer APIs). If want to help out without getting too involved picking up one +of tasks of our [help wanted issue list](https://github.com/ipfs-shipyard/py-ipfs-http-client/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) +would go a long way towards making this library more feature-complete. 👍 -Run: +### Bug reports - $ flit build && flit publish +You can submit bug reports using the +[GitHub issue tracker](https://github.com/ipfs/py-ipfs-http-client/issues). -## Re-generate and publish the documentation +### Setting up a local development environment -Run: + 1. Follow the instructions in the IPFS documentation to install go-IPFS into your `${PATH}`: + https://docs.ipfs.io/install/command-line/ + 2. Follow the instructions in the (Python) tox documentation to install the `tox` Python environment runner: + https://tox.readthedocs.io/en/latest/install.html + 3. Clone the GIT repository if you haven't already: + `git clone https://github.com/ipfs-shipyard/py-ipfs-http-client.git` - $ python docs/publish.py ipns-key-id +If you want to you can also make your local development version of +*py-ipfs-http-client* available to your Python environment by +[installing `flit`](https://flit.readthedocs.io/en/latest/#install) +and running `flit install --pth-file` from the repository root. -The command will also print a commandline that may be used to mirror the generated -documentation on systems other then the current one. +Please see the next section for how to run tests and contribute code +back into the project. -If you don't have the IPNS private key, you can still exercise the documentation -generation and publish process: - $ python docs/publish.py +### Pull requests -If you are publishing to an IPFS server that is remote, and protected by an HTTP reverse proxy -with TLS and basic authentication, run this instead: +Pull requests are welcome. Before submitting a new pull request, please +make sure that your code passes both the +[code formatting](https://www.python.org/dev/peps/pep-0008/) +(PEP-8 with tab indentation) and +[typing](https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html) +(PEP-484 using mypy) checks: - $ PY_IPFS_HTTP_CLIENT_DEFAULT_ADDR=/dns/yourserver.tld/tcp/5001/https PY_IPFS_HTTP_CLIENT_DEFAULT_USERNAME=basicauthuser PY_IPFS_HTTP_CLIENT_DEFAULT_PASSWORD=basicauthpassword python publish.py ipns-key-id + $ tox -e styleck -e typeck + +As well as the unit tests: + + $ tox -e py3 -e py3-httpx + +If you are unsure, don't hesitate to just submit your code, and a human will +take a look. 🙂 + +If you can, Please make sure to include new unit tests for new features or +changes in behavior. We aim to bring coverage to 100% at some point. + +#### Installing the pre-commit Hook + +You can arrange for the code style and typing tests to be run automatically +before each commit by installing the GIT `pre-commit` hook: + + $ ./tools/pre-commit --install + +### Chat with Us (IRC/Matrix) + +You can find us on [#py-ipfs on chat.freenode.org](http://webchat.freenode.net/?channels=%23py-ipfs) +or in our [Matrix chat room](https://matrix.to/#/#py-ipfs:ninetailed.ninja?via=ninetailed.ninja&via=librem.one). +Join us if you have any suggestions, questions or if you just want to discuss +IPFS and Python in general. + +Please note that the channel is not monitored all the time and hence you may +only receive a reply to your message later that day. Using Matrix makes it +easier to stay connected in the background, so please prefer the Matrix option +or use an IRC bouncer. + +## License + +This code is distributed under the terms of the [MIT license](https://opensource.org/licenses/MIT). Details can be found in the file +[LICENSE](LICENSE) in this repository.