Skip to content

Final changes for py-ipfs-http-client #181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
May 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,9 @@
'sphinx.ext.napoleon',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'recommonmark'
]

# Use reCommonMark for parsing text documents as MarkDown
source_parsers = {
'.md': 'recommonmark.parser.CommonMarkParser',
}

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

Expand Down Expand Up @@ -314,7 +310,8 @@
# External documentation link mapping
intersphinx_mapping = {
'python': ('https://docs.python.org/3', None),
'cid': ('https://py-cid.readthedocs.io/en/master/', None)
'cid': ('https://py-cid.readthedocs.io/en/master/', None),
'multiaddr': ('https://multiaddr.readthedocs.io/en/latest/', None)
}

# -- Napoleon settings ----------------------------------------------------
Expand Down Expand Up @@ -386,7 +383,7 @@ def import_object(self):
def format_signature(self):
"""Hide inheritance signature since it's not applicable helpful for
these classes."""
return ""
return "({0})".format(self.args) if self.args is not None else ""

class ClientClassDocumenter(ClientClassDocumenterBase):
objtype = "clientclass"
Expand Down
44 changes: 20 additions & 24 deletions docs/http_client_ref.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,23 @@ All commands are accessed through the ``ipfshttpclient.Client`` class.
### Utility Functions

```eval_rst
.. data:: ipfshttpclient.DEFAULT_HOST
.. data:: ipfshttpclient.DEFAULT_ADDR

The default hostname that the client library will attempt to connect to.
This may be overwritten on a per-client-instance basis using the ``host``
parameter of the :func:`~ipfshttpclient.connect` function.

.. data:: ipfshttpclient.DEFAULT_PORT

The default port number that the client library will attempt to connect to.
This may be overwritten on a per-client-instance basis using the ``port``
parameter of the :func:`~ipfshttpclient.connect` function.
The default IPFS API daemon location the client library will attempt to
connect to. By default this will have a value of ``multiaddr.Multiaddr("/dns/localhost/tcp/5001/http")``.

This may be overwritten on a per-client-instance basis using
the ``addr`` parameter of the :func:`~ipfshttpclient.connect` function.

.. data:: ipfshttpclient.DEFAULT_BASE

The default HTTP URL prefix (or “base”) that the client library will use.
This may be overwritten on a per-client-instance basis using the ``base``
parameter of the :func:`~ipfshttpclient.connect` function.
The default HTTP URL path prefix (or “base”) that the client library will use.
By default this will have a value of ``"api/v0"``.

This may be overwritten on a per-client-instance basis using the ``base``
parameter of the :func:`~ipfshttpclient.connect` function.

.. autofunction:: ipfshttpclient.connect(host=DEFAULT_HOST, port=DEFAULT_PORT, base=DEFAULT_BASE)
.. autofunction:: ipfshttpclient.connect(addr=DEFAULT_ADDR, base=DEFAULT_BASE)

.. autofunction:: ipfshttpclient.assert_version

Expand All @@ -42,25 +40,23 @@ All commands are accessed through the ``ipfshttpclient.Client`` class.

All methods accept the following parameters in their `kwargs`:

* **opts** (*dict*) – A mapping of custom IPFS API parameters to be sent along
with the regular parameters generated by the client
library
* **offline** ([*bool*](https://docs.python.org/3/library/functions.html#bool)) – Prevent the deamon from communicating with any remote IPFS node while performing the requested action?
* **opts** ([*dict*](https://docs.python.org/3/library/stdtypes.html#dict)) – A mapping of custom IPFS API parameters to be sent along with the regular parameters generated by the client library
* Values specified here will always override their respective counterparts
of the client library itself.
* **stream** (*bool*) – Return results incrementally as they arrive?
* **stream** ([*bool*](https://docs.python.org/3/library/functions.html#bool)) – Return results incrementally as they arrive?
* Each method called with `stream=True` will return a generator instead
of the documented value. If the return type is of type `list` then each
item of the given list will be yielded separately; if it is of type
`bytes` then arbitrary bags of bytes will be yielded that together form
a stream; finally, if it is of type `dict` then the single dictonary item
will be yielded once.
* **timeout** (**float**) – The number of seconds to wait of a daemon reply
before giving up
* **timeout** ([*float*](https://docs.python.org/3/library/functions.html#float)) – The number of seconds to wait of a daemon reply before giving up

```eval_rst
.. autoclientclass:: ipfshttpclient.Client(addr=DEFAULT_ADDR, base=DEFAULT_BASE)
:members:
:inherited-members:
:undoc-members:

.. autoclientclass:: ipfshttpclient.Client
:members:
:inherited-members:
:undoc-members:
```
8 changes: 6 additions & 2 deletions docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ DNF line: `sudo dnf install python3-flit`
Sphinx is the standard documentation framework for Python. Recommonmark is an extension that allows
Sphinx to process Markdown documentation as if it where reStructuredText.

APT line: `sudo apt install python3-sphinx python3-recommonmark`
DNF line: `sudo dnf install python3-sphinx python3-recommonmark`
<!-- APT line: `sudo apt install python3-sphinx python3-recommonmark` -->
<!--DNF line: `sudo dnf install python3-sphinx python3-recommonmark`-->

At least reCommonMark 0.5 is required, so install it using PIP:

`pip3 install recommonmark~=0.5.0`

## Hosting Documentation

Expand Down
2 changes: 1 addition & 1 deletion ipfshttpclient/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
###################################
from . import exceptions

from .client import DEFAULT_HOST, DEFAULT_PORT, DEFAULT_BASE
from .client import DEFAULT_ADDR, DEFAULT_BASE
from .client import VERSION_MINIMUM, VERSION_MAXIMUM
from .client import Client, assert_version, connect
12 changes: 8 additions & 4 deletions ipfshttpclient/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
import os
import warnings

DEFAULT_HOST = str(os.environ.get("PY_IPFS_HTTP_CLIENT_DEFAULT_HOST", 'localhost'))
DEFAULT_PORT = int(os.environ.get("PY_IPFS_HTTP_CLIENT_DEFAULT_PORT", 5001))
import multiaddr

DEFAULT_ADDR = multiaddr.Multiaddr(os.environ.get("PY_IPFS_HTTP_CLIENT_DEFAULT_ADDR", '/dns/localhost/tcp/5001/http'))
DEFAULT_BASE = str(os.environ.get("PY_IPFS_HTTP_CLIENT_DEFAULT_BASE", 'api/v0'))

VERSION_MINIMUM = "0.4.3"
Expand Down Expand Up @@ -64,7 +65,7 @@ def assert_version(version, minimum=VERSION_MINIMUM, maximum=VERSION_MAXIMUM):
raise exceptions.VersionMismatch(version, minimum, maximum)


def connect(host=DEFAULT_HOST, port=DEFAULT_PORT, base=DEFAULT_BASE,
def connect(addr=DEFAULT_ADDR, base=DEFAULT_BASE,
chunk_size=multipart.default_chunk_size, **defaults):
"""Create a new :class:`~ipfshttpclient.Client` instance and connect to the
daemon to validate that its version is supported.
Expand All @@ -87,7 +88,7 @@ def connect(host=DEFAULT_HOST, port=DEFAULT_PORT, base=DEFAULT_BASE,
:class:`~ipfshttpclient.Client`
"""
# Create client instance
client = Client(host, port, base, chunk_size, **defaults)
client = Client(addr, base, chunk_size, **defaults)

# Query version number from daemon and validate it
assert_version(client.version()['Version'])
Expand All @@ -106,6 +107,9 @@ class Client(files.Base, miscellaneous.Base):
as :func:`connect`, to prevent the client from checking for an active and
compatible version of the daemon.
"""

__doc__ += base.ClientBase.__doc__

bitswap = base.SectionProperty(bitswap.Section)
block = base.SectionProperty(block.Section)
bootstrap = base.SectionProperty(bootstrap.Section)
Expand Down
58 changes: 33 additions & 25 deletions ipfshttpclient/client/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import six

from . import DEFAULT_HOST, DEFAULT_PORT, DEFAULT_BASE
from . import DEFAULT_ADDR, DEFAULT_BASE

from .. import multipart, http

Expand Down Expand Up @@ -47,16 +47,19 @@ def __init__(self, cls):
self.__prop_cls__ = cls

def __get__(self, client_object, type=None):
try:
return client_object.__prop_objs__[self]
except AttributeError:
client_object.__prop_objs__ = {
self: self.__prop_cls__(client_object)
}
return client_object.__prop_objs__[self]
except KeyError:
client_object.__prop_objs__[self] = self.__prop_cls__(client_object)
return client_object.__prop_objs__[self]
if client_object is not None: # We are invoked on object
try:
return client_object.__prop_objs__[self]
except AttributeError:
client_object.__prop_objs__ = {
self: self.__prop_cls__(client_object)
}
return client_object.__prop_objs__[self]
except KeyError:
client_object.__prop_objs__[self] = self.__prop_cls__(client_object)
return client_object.__prop_objs__[self]
else: # We are invoked on class
return self.__prop_cls__


class SectionBase(object):
Expand All @@ -79,31 +82,36 @@ def chunk_size(self, value):


class ClientBase(object):
"""A TCP client for interacting with an IPFS daemon.

A :class:`~ipfshttpclient.Client` instance will not actually establish a
connection to the daemon until at least one of it's methods is called.

"""
Parameters
----------
host : str
Hostname or IP address of the computer running the ``ipfs daemon``
node (defaults to the local system)
port : int
The API port of the IPFS deamon (usually 5001)
addr : Union[bytes, str, multiaddr.Multiaddr]
The `MultiAddr <dweb:/ipns/multiformats.io/multiaddr/>`_ describing the
API daemon location, as used in the *API* key of `go-ipfs Addresses
section
<https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#addresses>`_

Supported addressing patterns are currently:

* ``/{dns,dns4,dns6,ip4,ip6}/<host>/tcp/<port>`` (HTTP)
* ``/{dns,dns4,dns6,ip4,ip6}/<host>/tcp/<port>/http`` (HTTP)
* ``/{dns,dns4,dns6,ip4,ip6}/<host>/tcp/<port>/https`` (HTTPS)

Additional forms (proxying) may be supported in the future.
base : str
Path of the deamon's API (currently always ``api/v0``)
The HTTP URL path prefix (or “base”) at which the API is exposed on the
API daemon
chunk_size : int
The size of the chunks to break uploaded files and text content into
"""

_clientfactory = http.HTTPClient

def __init__(self, host=DEFAULT_HOST, port=DEFAULT_PORT,
base=DEFAULT_BASE, chunk_size=multipart.default_chunk_size,
def __init__(self, addr=DEFAULT_ADDR, base=DEFAULT_BASE,
chunk_size=multipart.default_chunk_size,
**defaults):
"""Connects to the API port of an IPFS node."""

self.chunk_size = chunk_size

self._client = self._clientfactory(host, port, base, **defaults)
self._client = self._clientfactory(addr, base, **defaults)
50 changes: 0 additions & 50 deletions ipfshttpclient/client/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,56 +310,6 @@ def add(self, file, *files, **kwargs):
return resp


@base.returns_single_item
def file_ls(self, multihash, **kwargs):
"""Lists directory contents for Unix filesystem objects.

The result contains size information. For files, the child size is the
total size of the file contents. For directories, the child size is the
IPFS link size.

The path can be a prefixless reference; in this case, it is assumed
that it is an ``/ipfs/`` reference and not ``/ipns/``.

.. code-block:: python

>>> client.file_ls('QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D')
{
'Arguments': {'QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D':
'QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D'},
'Objects': {
'QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D': {
'Hash': 'QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D',
'Size': 0, 'Type': 'Directory',
'Links': [
{'Hash': 'Qmd2xkBfEwEs9oMTk77A6jrsgurpF3ugXSg7dtPNFkcNMV',
'Name': 'Makefile', 'Size': 163, 'Type': 'File'},
{'Hash': 'QmeKozNssnkJ4NcyRidYgDY2jfRZqVEoRGfipkgath71bX',
'Name': 'example', 'Size': 1463, 'Type': 'File'},
{'Hash': 'QmZAL3oHMQYqsV61tGvoAVtQLs1WzRe1zkkamv9qxqnDuK',
'Name': 'home', 'Size': 3947, 'Type': 'Directory'},
{'Hash': 'QmZNPyKVriMsZwJSNXeQtVQSNU4v4KEKGUQaMT61LPahso',
'Name': 'lib', 'Size': 268261, 'Type': 'Directory'},
{'Hash': 'QmSY8RfVntt3VdxWppv9w5hWgNrE31uctgTiYwKir8eXJY',
'Name': 'published-version', 'Size': 47, 'Type': 'File'}
]
}
}
}

Parameters
----------
multihash : str
The path to the object(s) to list links from

Returns
-------
dict
"""
args = (multihash,)
return self._client.request('/file/ls', args, decoder='json', **kwargs)


def get(self, cid, **kwargs):
"""Downloads a file, or directory of files from IPFS.

Expand Down
Loading