Skip to content

Commit

Permalink
Merge pull request #83 from Multi-Agent-io/development
Browse files Browse the repository at this point in the history
1.6.0 Removed ipfs_utils, added RWS checks, error messages
  • Loading branch information
PaTara43 authored Jan 18, 2023
2 parents e79df70 + ea84edd commit 7da9e85
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 136 deletions.
7 changes: 0 additions & 7 deletions docs/source/modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,3 @@ Utils
----------
.. automodule:: robonomicsinterface.utils
:members:

IPFS Utils
----------
.. automodule:: robonomicsinterface.ipfs_utils
:members: web_3_auth, ipfs_upload_content, ipfs_get_content


43 changes: 6 additions & 37 deletions docs/source/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ future transactions to be included in block. It saves time, but one may not know
One more argument while initializing is ``return_block_num``. If Set to ``True`` ALONG WITH ``wait_for_inclusion``, the
``extrinsic`` function will return a tuple of form ``(<extrinsic_hash>, <block_number-idx>)``.

If any extrinsic has failed, it well raise ``ExtrinsicFailedException`` with an error message inside.

Common Functions
++++++++++++++++

Expand Down Expand Up @@ -253,6 +255,8 @@ There are as well dedicated methods for convenient usage of RWS.
rws.get_auction(0)
rws.get_devices("4CqaroZnr25e43Ypi8Qe5NwbUYXzhxKqrfY5opnRzK4yG1mg")
rws.get_ledger("4CqaroZnr25e43Ypi8Qe5NwbUYXzhxKqrfY5opnRzK4yG1mg")
rws.get_days_left()
rws.is_in_sub(<owner_addr>, <device_addr>)
- Extrinsincs: `bid`, `set_devices`

Expand Down Expand Up @@ -423,7 +427,8 @@ Utils
++++++++

Utils module provides some helpful functions, among which there are IPFS ``Qm...`` hash encoding to 32 bytes length
string and vice-versa.
string and vice-versa. One more is generating an auth tuple for Web3-Auth gateways (more on that
`on Crust Wiki <https://wiki.crust.network/docs/en/buildIPFSWeb3AuthGW>`__).

.. code-block:: python
Expand All @@ -434,40 +439,4 @@ string and vice-versa.
# >>> '0xcc2d976220820d023b7170f520d3490e811ed988ae3d6221474ee97e559b0361'
ipfs_hash_decoded = ipfs_32_bytes_to_qm_hash("0xcc2d976220820d023b7170f520d3490e811ed988ae3d6221474ee97e559b0361")
# >>> 'Qmc5gCcjYypU7y28oCALwfSvxCBskLuPKWpK4qpterKC7z'
IPFS Utils
++++++++++

There is one more useful functionality: Content upload to IPFS via local or remote gateway (and IPFS content fetch). To use
the local gateway no additional parameters needed:

.. code-block:: python
from robonomicsinterface.utils import ipfs_get_content, ipfs_upload_content
content = "heeelo"
cid, size = ipfs_upload_content(content=content)
print(cid)
>>> QmeWzphuZbSqVKaxeYQ45VUeaHv18qSgPX4wpQAD44uuMt
content_ = ipfs_get_content(cid)
print(content_)
>>> b'heeelo'
One may also pass a gateway address and use Web3-authenticate gateways! See more info
`on Crust Wiki <https://wiki.crust.network/docs/en/buildIPFSWeb3AuthGW>`__.

.. code-block:: python
from robonomicsinterface.utils import ipfs_get_content, ipfs_upload_content, web_3_auth
content = "heeelo"
auth = web_3_auth(tester_tokens_seed)
cid, size = ipfs_upload_content(content=content, gateway="web3_gateway_url", auth=auth)
print(cid)
>>> QmeWzphuZbSqVKaxeYQ45VUeaHv18qSgPX4wpQAD44uuMt
content_ = ipfs_get_content(cid, gateway="web3_gateway_url")
print(content_)
>>> b'heeelo'
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "robonomics-interface"
version = "1.5.0"
version = "1.6.0"
description = "Robonomics wrapper over https://github.com/polkascan/py-substrate-interface created to facilitate programming with Robonomics"
authors = ["Pavel Tarasov <[email protected]>"]
license = "Apache-2.0"
Expand Down
1 change: 0 additions & 1 deletion robonomicsinterface/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,3 @@
SubEvent,
Subscriber,
)
from .ipfs_utils import web_3_auth, ipfs_upload_content, ipfs_get_content
4 changes: 1 addition & 3 deletions robonomicsinterface/classes/chain_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,4 @@ def _get_block_any(block_: tp.Union[int, str]) -> list:
return extrinsic_.value

else:
return _get_block_any(block)[extrinsic-1].value


return _get_block_any(block)[extrinsic - 1].value
6 changes: 4 additions & 2 deletions robonomicsinterface/classes/liability.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ def get_latest_index(self, block_hash: tp.Optional[str] = None) -> tp.Optional[i

logger.info("Fetching total number of liabilities in chain.")

next_index: tp.Optional[int] = self._service_functions.chainstate_query("Liability", "NextIndex", block_hash=block_hash)
next_index: tp.Optional[int] = self._service_functions.chainstate_query(
"Liability", "NextIndex", block_hash=block_hash
)
if not next_index:
return None
else:
Expand Down Expand Up @@ -135,7 +137,7 @@ def create(
latest_index = 0
return latest_index, liability_creation_transaction_hash
index: int = latest_index
for liabilities in reversed(range(latest_index+1)):
for liabilities in reversed(range(latest_index + 1)):
if (
self.get_agreement(liabilities)["promisee_signature"][KEYPAIR_TYPE[promisee_signature_crypto_type]]
== promisee_params_signature
Expand Down
54 changes: 54 additions & 0 deletions robonomicsinterface/classes/rws.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import time
import typing as tp

from logging import getLogger
Expand Down Expand Up @@ -91,6 +92,59 @@ def get_ledger(

return self._service_functions.chainstate_query("RWS", "Ledger", address, block_hash=block_hash)

def get_days_left(
self, addr: tp.Optional[str] = None, block_hash: tp.Optional[str] = None
) -> tp.Union[int, bool]:
"""
Check if RWS subscription is still active for the address.
:param addr: Possible subscription owner. If ``None`` - account address.
:param block_hash: Retrieves data as of passed block hash.
:return: Number of days left if subscription is active, ``False`` if no active subscription.
"""

address: str = addr or self.account.get_address()

logger.info(f"Fetching RWS subscription status for {address}")

ledger: LedgerTyping = self._service_functions.chainstate_query("RWS", "Ledger", address, block_hash=block_hash)
if not ledger:
return False
unix_time_sub_expire: int = ledger["issue_time"] + 86400 * 1000 * ledger["kind"]["Daily"]["days"]
days_left: float = (unix_time_sub_expire - time.time() * 1000) / 86400000
if days_left >= 0:
return int(days_left)
else:
return False

def is_in_sub(
self, sub_owner_addr: str, addr: tp.Optional[str] = None, block_hash: tp.Optional[str] = None
) -> bool:
"""
Check whether ``addr`` is a device of ``sub_owner_addr`` subscription.
:param sub_owner_addr: Subscription owner address.
:param addr: Address to check. If ``None`` - account address.
:param block_hash: Retrieves data as of passed block hash.
:return: ``True`` if ``addr`` is in ``sub_owner_addr`` device list, ``False`` otherwise.
"""

logger.info(f"Fetching list of RWS devices set by owner {sub_owner_addr}")

address: str = addr or self.account.get_address()
devices: tp.List[tp.Optional[str]] = self._service_functions.chainstate_query(
"RWS", "Devices", sub_owner_addr, block_hash=block_hash
)

if address in devices:
return True
else:
return False

def bid(self, index: int, amount: int) -> str:
"""
Bid to win a subscription!
Expand Down
2 changes: 1 addition & 1 deletion robonomicsinterface/classes/service_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def extrinsic(
if self.wait_for_inclusion:

if not receipt.is_success:
raise ExtrinsicFailedException()
raise ExtrinsicFailedException(receipt.error_message)

block_num: int = self.interface.get_block_number(receipt.block_hash)
logger.info(f"Extrinsic included in block {block_num}")
Expand Down
8 changes: 0 additions & 8 deletions robonomicsinterface/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,3 @@ class InvalidExtrinsicHash(Exception):
"""

pass


class FailedToUploadFile(Exception):
"""
Failed to upload a file to Crust Network.
"""

pass
1 change: 0 additions & 1 deletion robonomicsinterface/ipfs_utils/__init__.py

This file was deleted.

74 changes: 0 additions & 74 deletions robonomicsinterface/ipfs_utils/ipfs_gateway_interaction.py

This file was deleted.

2 changes: 1 addition & 1 deletion robonomicsinterface/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
AuctionTyping = tp.Dict[str, tp.Union[str, int, tp.Dict[str, tp.Dict[str, tp.Dict[str, int]]]]]
DatalogTyping = tp.Tuple[int, tp.Union[int, str]]
DigitalTwinTyping = tp.List[tp.Tuple[str, str]]
LedgerTyping = tp.Dict[str, tp.Union[int, tp.Dict[str, tp.Dict[str, tp.Dict[str, int]]]]]
LedgerTyping = tp.Dict[str, tp.Union[int, tp.Dict[str, tp.Dict[str, int]]]]
LiabilityTyping = tp.Dict[str, tp.Union[tp.Dict[str, tp.Union[str, int]], str]]
ListenersResponse = tp.Dict[str, tp.Union[str, tp.List[str], int]]
QueryParams = tp.Optional[tp.Union[tp.List[tp.Union[str, int]], str, int]]
Expand Down
14 changes: 14 additions & 0 deletions robonomicsinterface/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,17 @@ def str_to_scalebytes(data: tp.Union[int, str], type_str: str) -> ScaleBytes:

scale_obj: ScaleType = RuntimeConfiguration().create_scale_object(type_str)
return scale_obj.encode(data)


def web_3_auth(seed: str) -> tp.Tuple[str, str]:
"""
Get authentication header for a Web3-auth IPFS gateway.
:param seed: Substrate account seed in any, mnemonic or raw form.
:return: Authentication header.
"""

keypair: Keypair = create_keypair(seed)
return f"sub-{keypair.ss58_address}", f"0x{keypair.sign(keypair.ss58_address).hex()}"

0 comments on commit 7da9e85

Please sign in to comment.