From 0049a93c27f3eb13ad7e8cc4c302dad94bbae0f5 Mon Sep 17 00:00:00 2001 From: Vincent Texier <vit@free.fr> Date: Tue, 10 Jul 2018 11:55:07 +0200 Subject: [PATCH] issue #56 WIP - Implement Client.post() method everywhere needed --- duniterpy/api/bma/blockchain.py | 163 +++++++++++------------ duniterpy/api/bma/network.py | 166 ++++++++++++------------ duniterpy/api/bma/tx.py | 27 ++-- duniterpy/api/bma/wot.py | 70 +++++----- examples/create_and_publish_identity.py | 45 +++---- examples/save_revoke_document.py | 72 +++++----- examples/send_certification.py | 58 +++++---- examples/send_transaction.py | 48 ++++--- 8 files changed, 323 insertions(+), 326 deletions(-) diff --git a/duniterpy/api/bma/blockchain.py b/duniterpy/api/bma/blockchain.py index c79b8ecc..4026d392 100644 --- a/duniterpy/api/bma/blockchain.py +++ b/duniterpy/api/bma/blockchain.py @@ -16,6 +16,10 @@ # Caner Candan <caner@candan.fr>, http://caner.candan.fr # vit import logging +from typing import Union + +from aiohttp import ClientSession + from duniterpy.api.client import Client, RESPONSE_AIOHTTP logger = logging.getLogger("duniter/blockchain") @@ -174,76 +178,75 @@ BLOCK_NUMBERS_SCHEMA = { } PARAMETERS_SCHEMA = { - "type": "object", - "properties": + "type": "object", + "properties": { - "currency": { - "type": "string" - }, - "c": { - "type": "number" - }, - "dt": { - "type": "number" - }, - "ud0": { - "type": "number" - }, - "sigPeriod": { - "type": "number" - }, - "sigStock": { - "type": "number" - }, - "sigWindow": { - "type": "number" - }, - "sigValidity": { - "type": "number" - }, - "sigQty": { - "type": "number" - }, - "xpercent": { - "type": "number" - }, - "msValidity": { - "type": "number" - }, - "stepMax": { - "type": "number" - }, - "medianTimeBlocks": { - "type": "number" - }, - "avgGenTime": { - "type": "number" - }, - "dtDiffEval": { - "type": "number" - }, - "percentRot": { - "type": "number" - }, - "udTime0": { - "type": "number" - }, - "udReevalTime0": { - "type": "number" - }, - "dtReeval": { - "type": "number" - } + "currency": { + "type": "string" }, - "required": ["currency", "c", "dt", "ud0", "sigPeriod", "sigValidity", "sigQty", "xpercent", "sigStock", - "sigWindow", "msValidity", "stepMax", "medianTimeBlocks", - "avgGenTime", "dtDiffEval", "percentRot", "udTime0", "udReevalTime0", "dtReeval"] - } - + "c": { + "type": "number" + }, + "dt": { + "type": "number" + }, + "ud0": { + "type": "number" + }, + "sigPeriod": { + "type": "number" + }, + "sigStock": { + "type": "number" + }, + "sigWindow": { + "type": "number" + }, + "sigValidity": { + "type": "number" + }, + "sigQty": { + "type": "number" + }, + "xpercent": { + "type": "number" + }, + "msValidity": { + "type": "number" + }, + "stepMax": { + "type": "number" + }, + "medianTimeBlocks": { + "type": "number" + }, + "avgGenTime": { + "type": "number" + }, + "dtDiffEval": { + "type": "number" + }, + "percentRot": { + "type": "number" + }, + "udTime0": { + "type": "number" + }, + "udReevalTime0": { + "type": "number" + }, + "dtReeval": { + "type": "number" + } + }, + "required": ["currency", "c", "dt", "ud0", "sigPeriod", "sigValidity", "sigQty", "xpercent", "sigStock", + "sigWindow", "msValidity", "stepMax", "medianTimeBlocks", + "avgGenTime", "dtDiffEval", "percentRot", "udTime0", "udReevalTime0", "dtReeval"] +} MEMBERSHIPS_SCHEMA = { - "type": "object", - "properties": + "type": "object", + "properties": { "pubkey": { "type": "string" @@ -279,9 +282,8 @@ MEMBERSHIPS_SCHEMA = { } } }, - "required": ["pubkey", "uid", "sigDate", "memberships"] - } - + "required": ["pubkey", "uid", "sigDate", "memberships"] +} BLOCKS_SCHEMA = { "type": "array", @@ -323,15 +325,15 @@ async def memberships(client: Client, search: str) -> dict: return await client.get(MODULE + '/memberships/%s' % search, schema=MEMBERSHIPS_SCHEMA) -async def membership(client: Client, _membership: str): +async def membership(client: Client, membership_signed_raw: str): """ POST a Membership document :param client: Client to connect to the api - :param _membership: Membership signed raw document + :param membership_signed_raw: Membership signed raw document :rtype: aiohttp.ClientResponse """ - return await client.post(MODULE + '/membership', {'membership': _membership}, rtype=RESPONSE_AIOHTTP) + return await client.post(MODULE + '/membership', {'membership': membership_signed_raw}, rtype=RESPONSE_AIOHTTP) async def current(client: Client) -> dict: @@ -344,22 +346,21 @@ async def current(client: Client) -> dict: return await client.get(MODULE + '/current', schema=BLOCK_SCHEMA) -async def block(client: Client, number: int = 0, _block: dict = None, signature: str = None): +async def block(client: Client, number: int = 0, block_raw: str = None, signature: str = None) -> Union[dict, + ClientSession]: """ GET/POST a block from/to the blockchain :param client: Client to connect to the api :param number: Block number to get - :param dict _block: Block document to post - :param str signature: Signature of the block document issuer + :param block_raw: Block document to post + :param signature: Signature of the block document issuer :rtype: dict """ - - # client = API(connection, MODULE) - # # POST block - # if _block is not None and signature is not None: - # return await client.requests_post('/block', block=_block, signature=signature) - + # POST block + if block_raw is not None and signature is not None: + return await client.post(MODULE + '/block', {'block': block_raw, 'signature': signature}, + rtype=RESPONSE_AIOHTTP) # GET block return await client.get(MODULE + '/block/%d' % number, schema=BLOCK_SCHEMA) diff --git a/duniterpy/api/bma/network.py b/duniterpy/api/bma/network.py index eedaaecc..cebb5ba0 100644 --- a/duniterpy/api/bma/network.py +++ b/duniterpy/api/bma/network.py @@ -16,90 +16,92 @@ # Caner Candan <caner@candan.fr>, http://caner.candan.fr # vit import logging -from duniterpy.api.client import Client -from duniterpy.documents.peer import Peer + +from aiohttp import ClientSession + +from duniterpy.api.client import Client, RESPONSE_AIOHTTP logger = logging.getLogger("duniter/network") MODULE = 'network' PEERING_SCHEMA = { - "type": "object", - "properties": { - "version": { - "type": ["number", "string"] - }, - "currency": { - "type": "string" - }, - "pubkey": { - "type": "string" - }, - "endpoints": { - "type": "array", - "items": { - "type": "string" - } - }, - "signature": { - "type": "string" - } + "type": "object", + "properties": { + "version": { + "type": ["number", "string"] + }, + "currency": { + "type": "string" }, - "required": ["version", "currency", "pubkey", "endpoints", "signature"] - } + "pubkey": { + "type": "string" + }, + "endpoints": { + "type": "array", + "items": { + "type": "string" + } + }, + "signature": { + "type": "string" + } + }, + "required": ["version", "currency", "pubkey", "endpoints", "signature"] +} PEERS_SCHEMA = schema = { - "type": ["object"], - "properties": { - "depth": { - "type": "number" - }, - "nodesCount": { - "type": "number" - }, - "leavesCount": { - "type": "number" - }, - "root": { - "type": "string" - }, - "hash": { - "type": "string" - }, - "value": { - "type": "object", - "properties": { - "version": { - "type": "string" - }, - "currency": { - "type": "string" - }, - "pubkey": { - "type": "string" - }, - "endpoints": { - "type": "array", - "items": { - "type": "string" - } - }, - "signature": { + "type": ["object"], + "properties": { + "depth": { + "type": "number" + }, + "nodesCount": { + "type": "number" + }, + "leavesCount": { + "type": "number" + }, + "root": { + "type": "string" + }, + "hash": { + "type": "string" + }, + "value": { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "currency": { + "type": "string" + }, + "pubkey": { + "type": "string" + }, + "endpoints": { + "type": "array", + "items": { "type": "string" } }, - "required": ["version", "currency", "pubkey", "endpoints", "signature"] - } - }, - "oneOf": [ - { - "required": ["depth", "nodesCount", "leavesCount", "root"] + "signature": { + "type": "string" + } }, - { - "required": ["hash", "value"] - } - ] - } + "required": ["version", "currency", "pubkey", "endpoints", "signature"] + } + }, + "oneOf": [ + { + "required": ["depth", "nodesCount", "leavesCount", "root"] + }, + { + "required": ["hash", "value"] + } + ] +} async def peering(client: Client) -> dict: @@ -127,16 +129,12 @@ async def peers(client: Client, leaves: bool = False, leaf: str = ""): return await client.get(MODULE + '/peering/peers', {"leaf": leaf}, schema=PEERS_SCHEMA) -# async def peer(client: Client, entry: Peer = None, signature: str = None) -> dict: -# """ -# POST a Peer document with his signature -# -# :param client: Client to connect to the api -# :param entry: Peer document -# :param signature: Signature of the document issuer -# :rtype: dict -# """ -# -# client = API(connection, MODULE) -# r = await client.requests_post('/peering/peers', entry=entry, signature=signature) -# return r +async def peer(client: Client, peer_signed_raw: str) -> ClientSession: + """ + POST a Peer signed raw document + + :param client: Client to connect to the api + :param peer_signed_raw: Peer signed raw document + :rtype: ClientSession + """ + return await client.post(MODULE + '/peering/peers', {'peer': peer_signed_raw}, rtype=RESPONSE_AIOHTTP) diff --git a/duniterpy/api/bma/tx.py b/duniterpy/api/bma/tx.py index dfeae417..a716fe15 100644 --- a/duniterpy/api/bma/tx.py +++ b/duniterpy/api/bma/tx.py @@ -16,8 +16,10 @@ # Caner Candan <caner@candan.fr>, http://caner.candan.fr # vit import logging -from duniterpy.api.client import Client -from duniterpy.documents import Transaction + +from aiohttp import ClientSession + +from duniterpy.api.client import Client, RESPONSE_AIOHTTP logger = logging.getLogger("duniter/tx") @@ -209,18 +211,15 @@ async def history(client: Client, pubkey: str) -> dict: return await client.get(MODULE + '/history/%s' % pubkey, schema=HISTORY_SCHEMA) -# async def process(client: Client, transaction: Transaction): -# """ -# POST a transaction -# -# :param client: Client to connect to the api -# :param transaction: Transaction document -# :rtype: aiohttp.ClientResponse -# """ -# client = API(connection, MODULE) -# -# r = await client.requests_post('/process', transaction=transaction) -# return r +async def process(client: Client, transaction_signed_raw: str) -> ClientSession: + """ + POST a transaction raw document + + :param client: Client to connect to the api + :param transaction_signed_raw: Transaction signed raw document + :rtype: ClientResponse + """ + return await client.post(MODULE + '/process', {'transaction': transaction_signed_raw}, rtype=RESPONSE_AIOHTTP) async def sources(client: Client, pubkey: str): diff --git a/duniterpy/api/bma/wot.py b/duniterpy/api/bma/wot.py index 4b655d54..01e4cb4b 100644 --- a/duniterpy/api/bma/wot.py +++ b/duniterpy/api/bma/wot.py @@ -16,7 +16,10 @@ # Caner Candan <caner@candan.fr>, http://caner.candan.fr # vit import logging -from duniterpy.api.client import Client + +from aiohttp import ClientSession + +from duniterpy.api.client import Client, RESPONSE_AIOHTTP logger = logging.getLogger("duniter/wot") @@ -97,7 +100,6 @@ CERTIFICATIONS_SCHEMA = { "required": ["pubkey", "uid", "isMember", "certifications"] } - MEMBERS_SCHEMA = { "type": "object", "properties": { @@ -117,7 +119,6 @@ MEMBERS_SCHEMA = { "required": ["results"] } - REQUIREMENTS_SCHEMA = { "type": "object", "properties": { @@ -298,46 +299,37 @@ LOOKUP_SCHEMA = { } -# async def add(client: Client, identity: str) -> dict: -# """ -# POST identity document -# -# :param duniterpy.api.bma.ConnectionHandler connection: Connection handler instance -# :param duniterpy.documents.certification.Identity identity: Identity document -# :rtype: aiohttp.ClientResponse -# """ -# client = API(connection, URL_PATH) -# -# r = await client.requests_post('/add', identity=identity) -# return r +async def add(client: Client, identity_signed_raw: str) -> ClientSession: + """ + POST identity raw document + :param client: Client to connect to the api + :param identity_signed_raw: Identity raw document + :rtype: aiohttp.ClientResponse + """ + return await client.post(MODULE + '/add', {'identity': identity_signed_raw}, rtype=RESPONSE_AIOHTTP) -# async def certify(connection, cert): -# """ -# POST certification document -# -# :param duniterpy.api.bma.ConnectionHandler connection: Connection handler instance -# :param duniterpy.documents.certification.Certification cert: Certification document -# :rtype: aiohttp.ClientResponse -# """ -# client = API(connection, URL_PATH) -# -# r = await client.requests_post('/certify', cert=cert) -# return r +async def certify(client: Client, certification_signed_raw: str) -> ClientSession: + """ + POST certification raw document -# async def revoke(connection, revocation): -# """ -# POST revocation document -# -# :param duniterpy.api.bma.ConnectionHandler connection: Connection handler instance -# :param duniterpy.documents.certification.Revocation revocation: Certification document -# :rtype: aiohttp.ClientResponse -# """ -# client = API(connection, URL_PATH) -# -# r = await client.requests_post('/revoke', revocation=revocation) -# return r + :param client: Client to connect to the api + :param certification_signed_raw: Certification raw document + :rtype: aiohttp.ClientResponse + """ + return await client.post(MODULE + '/certify', {'cert': certification_signed_raw}, rtype=RESPONSE_AIOHTTP) + + +async def revoke(client: Client, revocation_signed_raw: str) -> ClientSession: + """ + POST revocation document + + :param client: Client to connect to the api + :param revocation_signed_raw: Certification raw document + :rtype: aiohttp.ClientResponse + """ + return await client.post(MODULE + '/revoke', {'revocation': revocation_signed_raw}, rtype=RESPONSE_AIOHTTP) async def lookup(client: Client, search: str) -> dict: diff --git a/examples/create_and_publish_identity.py b/examples/create_and_publish_identity.py index 60ba1d92..f73a8dfd 100644 --- a/examples/create_and_publish_identity.py +++ b/examples/create_and_publish_identity.py @@ -1,13 +1,11 @@ import asyncio -import aiohttp import getpass import duniterpy.api.bma as bma -from duniterpy.api.endpoint import SecuredBMAEndpoint +from duniterpy.api.client import Client from duniterpy.documents import BlockUID, Identity from duniterpy.key import SigningKey - # CONFIG ####################################### # You can either use a complete defined endpoint : [NAME_OF_THE_API] [DOMAIN] [IPv4] [IPv6] [PORT] @@ -15,23 +13,18 @@ from duniterpy.key import SigningKey # Here we use the secure BASIC_MERKLED_API (BMAS) BMAS_ENDPOINT = "BMAS g1-test.duniter.org 443" -# Your unique identifier in the Web of Trust -UID = "MyIdentityTest" ################################################ -# Latest duniter-python-api is asynchronous and you have to create an aiohttp session to send request -# ( http://pythonhosted.org/aiohttp ) -AIOHTTP_SESSION = aiohttp.ClientSession() -def get_identity_document(current_block, uid, salt, password): +def get_identity_document(current_block: dict, uid: str, salt: str, password: str) -> Identity: """ Get an Identity document - :param dict current_block: Current block data - :param str uid: Unique Identifier - :param str salt: Passphrase of the account - :param str password: Password of the account + :param current_block: Current block data + :param uid: Unique IDentifier + :param salt: Passphrase of the account + :param password: Password of the account :rtype: Identity """ @@ -62,11 +55,18 @@ async def main(): """ Main code """ + # Create Client from endpoint string in Duniter format + client = Client(BMAS_ENDPOINT) + + # Get the node summary infos to test the connection + response = await client(bma.node.summary) + print(response) - # connection handler from BMA endpoint - connection = SecuredBMAEndpoint.from_inline(BMAS_ENDPOINT).conn_handler(AIOHTTP_SESSION) # capture current block to get version and currency and blockstamp - current_block = await bma.blockchain.current(connection) + current_block = await client(bma.blockchain.current) + + # prompt entry + uid = input("Enter your Unique IDentifier (pseudonym): ") # prompt hidden user entry salt = getpass.getpass("Enter your passphrase (salt): ") @@ -75,18 +75,19 @@ async def main(): password = getpass.getpass("Enter your password: ") # create our signed identity document - identity = get_identity_document(current_block, UID, salt, password) + identity = get_identity_document(current_block, uid, salt, password) # send the identity document to the node - response = await bma.wot.add(connection, identity.signed_raw()) + response = await client(bma.wot.add, identity.signed_raw()) if response.status == 200: print(await response.text()) else: print("Error while publishing identity : {0}".format(await response.text())) - response.close() + + # Close client aiohttp session + await client.close() + # Latest duniter-python-api is asynchronous and you have to use asyncio, an asyncio loop and a "as" on the data. # ( https://docs.python.org/3/library/asyncio.html ) - -with AIOHTTP_SESSION: - asyncio.get_event_loop().run_until_complete(main()) +asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/save_revoke_document.py b/examples/save_revoke_document.py index ae08e412..e5fd24e1 100644 --- a/examples/save_revoke_document.py +++ b/examples/save_revoke_document.py @@ -1,11 +1,11 @@ import asyncio -import aiohttp +import getpass +import os + import duniterpy.api.bma as bma -from duniterpy.api.endpoint import SecuredBMAEndpoint +from duniterpy.api.client import Client from duniterpy.documents import Revocation, BlockUID, Identity from duniterpy.key import SigningKey -import getpass -import os if "XDG_CONFIG_HOME" in os.environ: home_path = os.environ["XDG_CONFIG_HOME"] @@ -26,27 +26,27 @@ BMAS_ENDPOINT = "BMAS g1-test.duniter.org 443" # WARNING : Hide this file in a safe and secure place # If one day you forget your credentials, # you'll have to use your private key instead -REVOKE_DOCUMENT_FILE_PATH = os.path.join(home_path, "duniter_account_revoke_document.txt") - -################################################ -AIOHTTP_SESSION = aiohttp.ClientSession() +REVOCATION_DOCUMENT_FILE_PATH = os.path.join(home_path, "duniter_account_revocation_document.txt") # Current protocol version PROTOCOL_VERSION = 10 -async def get_identity_document(connection, currency, pubkey): +################################################ + + +async def get_identity_document(client: Client, currency: str, pubkey: str) -> Identity: """ Get the Identity document of the pubkey - :param bma.connection.ConnectionHandler connection: Connection handler - :param str currency: Currency name - :param str pubkey: Public key + :param client: Client to connect to the api + :param currency: Currency name + :param pubkey: Public key :rtype: Identity """ # Here we request for the path wot/lookup/pubkey - lookup_data = await bma.wot.lookup(connection, pubkey) + lookup_data = await client(bma.wot.lookup, pubkey) # init vars uid = None @@ -74,28 +74,34 @@ async def get_identity_document(connection, currency, pubkey): ) -def get_revoke_document(identity, salt, password): +def get_signed_raw_revocation_document(identity: Identity, salt: str, password: str) -> str: """ Generate account revocation document for given identity - :param Identity identity: Self Certification of the identity - :param str salt: Salt - :param str password: Password + :param identity: Self Certification of the identity + :param salt: Salt + :param password: Password - :return: the raw signed revokation document :rtype: str """ - document = Revocation(PROTOCOL_VERSION, identity.currency, identity.pubkey, "") + revocation = Revocation(PROTOCOL_VERSION, identity.currency, identity.pubkey, "") key = SigningKey(salt, password) - document.sign(identity, [key]) - return document.signed_raw(identity) + revocation.sign(identity, [key]) + return revocation.signed_raw(identity) async def main(): """ Main code """ + # Create Client from endpoint string in Duniter format + client = Client(BMAS_ENDPOINT) + + # Get the node summary infos to test the connection + response = await client(bma.node.summary) + print(response) + # prompt hidden user entry salt = getpass.getpass("Enter your passphrase (salt): ") @@ -113,27 +119,27 @@ async def main(): print("Bad credentials!") exit(0) - # connection handler from BMAS endpoint - connection = SecuredBMAEndpoint.from_inline(BMAS_ENDPOINT).conn_handler(AIOHTTP_SESSION) # capture current block to get currency name - current_block = await bma.blockchain.current(connection) + current_block = await client(bma.blockchain.current) # create our Identity document to sign the revoke document - identity_document = await get_identity_document(connection, current_block['currency'], pubkey) + identity_document = await get_identity_document(client, current_block['currency'], pubkey) # get the revoke document - revoke_document = get_revoke_document(identity_document, salt, password) + revocation_signed_raw_document = get_signed_raw_revocation_document(identity_document, salt, password) # save revoke document in a file - fp = open(REVOKE_DOCUMENT_FILE_PATH, 'w') - fp.write(revoke_document) + fp = open(REVOCATION_DOCUMENT_FILE_PATH, 'w') + fp.write(revocation_signed_raw_document) fp.close() # document saved - print("Revoke document saved in %s" % REVOKE_DOCUMENT_FILE_PATH) + print("Revocation document saved in %s" % REVOCATION_DOCUMENT_FILE_PATH) + + # Close client aiohttp session + await client.close() -with AIOHTTP_SESSION: - # Latest duniter-python-api is asynchronous and you have to use asyncio, an asyncio loop and a "as" on the data. - # ( https://docs.python.org/3/library/asyncio.html ) - asyncio.get_event_loop().run_until_complete(main()) +# Latest duniter-python-api is asynchronous and you have to use asyncio, an asyncio loop and a "as" on the data. +# ( https://docs.python.org/3/library/asyncio.html ) +asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/send_certification.py b/examples/send_certification.py index 1391a189..0da9a8ee 100644 --- a/examples/send_certification.py +++ b/examples/send_certification.py @@ -1,12 +1,11 @@ import asyncio -import aiohttp import getpass + import duniterpy.api.bma as bma -from duniterpy.api.endpoint import SecuredBMAEndpoint +from duniterpy.api.client import Client from duniterpy.documents import BlockUID, Identity, Certification from duniterpy.key import SigningKey - # CONFIG ####################################### # You can either use a complete defined endpoint : [NAME_OF_THE_API] [DOMAIN] [IPv4] [IPv6] [PORT] @@ -14,25 +13,22 @@ from duniterpy.key import SigningKey # Here we use the secure BASIC_MERKLED_API (BMAS) BMAS_ENDPOINT = "BMAS g1-test.duniter.org 443" -################################################ -# Latest duniter-python-api is asynchronous and you have to create an aiohttp session to send request -# ( http://pythonhosted.org/aiohttp ) -AIOHTTP_SESSION = aiohttp.ClientSession() +################################################ -async def get_identity_document(connection, current_block, pubkey): +async def get_identity_document(client: Client, current_block: dict, pubkey: str) -> Identity: """ Get the identity document of the pubkey - :param bma.connection.ConnectionHandler connection: Connection handler - :param dict current_block: Current block data - :param str pubkey: UID/Public key + :param client: Client to connect to the api + :param current_block: Current block data + :param pubkey: UID/Public key :rtype: Identity """ # Here we request for the path wot/lookup/pubkey - lookup_data = await bma.wot.lookup(connection, pubkey) + lookup_data = await client(bma.wot.lookup, pubkey) # init vars uid = None @@ -60,15 +56,16 @@ async def get_identity_document(connection, current_block, pubkey): ) -def get_certification_document(current_block, self_cert_document, from_pubkey, salt, password): +def get_certification_document(current_block: dict, self_cert_document: Identity, from_pubkey: str, salt: str, + password: str) -> Certification: """ Create and return a Certification document - :param dict current_block: Current block data - :param Identity self_cert_document: Identity document - :param str from_pubkey: Pubkey of the certifier - :param str salt: Secret salt (DO NOT SHOW IT ANYWHERE, IT IS SECRET !!!) - :param str password: Secret password (DO NOT SHOW IT ANYWHERE, IT IS SECRET !!!) + :param current_block: Current block data + :param self_cert_document: Identity document + :param from_pubkey: Pubkey of the certifier + :param salt: Secret salt (DO NOT SHOW IT ANYWHERE, IT IS SECRET !!!) + :param password: Secret password (DO NOT SHOW IT ANYWHERE, IT IS SECRET !!!) :rtype: Certification """ @@ -92,8 +89,12 @@ async def main(): """ Main code """ - # connection handler from BMA endpoint - connection = SecuredBMAEndpoint.from_inline(BMAS_ENDPOINT).conn_handler(AIOHTTP_SESSION) + # Create Client from endpoint string in Duniter format + client = Client(BMAS_ENDPOINT) + + # Get the node summary infos to test the connection + response = await client(bma.node.summary) + print(response) # prompt hidden user entry salt = getpass.getpass("Enter your passphrase (salt): ") @@ -108,25 +109,26 @@ async def main(): pubkey_to = input("Enter certified pubkey: ") # capture current block to get version and currency and blockstamp - current_block = await bma.blockchain.current(connection) + current_block = await client(bma.blockchain.current) # create our Identity document to sign the Certification document - identity = await get_identity_document(connection, current_block, pubkey_to) + identity = await get_identity_document(client, current_block, pubkey_to) # send the Certification document to the node certification = get_certification_document(current_block, identity, pubkey_from, salt, password) # Here we request for the path wot/certify - response = await bma.wot.certify(connection, certification.signed_raw(identity)) + response = await client(bma.wot.certify, certification.signed_raw(identity)) if response.status == 200: print(await response.text()) else: print("Error while publishing certification: {0}".format(await response.text())) - response.close() -with AIOHTTP_SESSION: + # Close client aiohttp session + await client.close() + - # Latest duniter-python-api is asynchronous and you have to use asyncio, an asyncio loop and a "as" on the data. - # ( https://docs.python.org/3/library/asyncio.html ) - asyncio.get_event_loop().run_until_complete(main()) +# Latest duniter-python-api is asynchronous and you have to use asyncio, an asyncio loop and a "as" on the data. +# ( https://docs.python.org/3/library/asyncio.html ) +asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/send_transaction.py b/examples/send_transaction.py index 98b6d9fe..e169d782 100644 --- a/examples/send_transaction.py +++ b/examples/send_transaction.py @@ -1,9 +1,8 @@ import asyncio import getpass -import aiohttp from duniterpy.api import bma -from duniterpy.api.endpoint import SecuredBMAEndpoint +from duniterpy.api.client import Client from duniterpy.documents import BlockUID, Transaction from duniterpy.documents.transaction import InputSource, OutputSource, Unlock, SIGParameter from duniterpy.grammars.output import Condition, SIG @@ -16,26 +15,21 @@ from duniterpy.key import SigningKey # Here we use the secure BASIC_MERKLED_API (BMAS) BMAS_ENDPOINT = "BMAS g1-test.duniter.org 443" - -################################################ - - -# Latest duniter-python-api is asynchronous and you have to create an aiohttp session to send request -# ( http://pythonhosted.org/aiohttp ) -AIOHTTP_SESSION = aiohttp.ClientSession() - # Version of the transaction document TRANSACTION_VERSION = 10 -def get_transaction_document(current_block, source, from_pubkey, to_pubkey): +################################################ + + +def get_transaction_document(current_block: dict, source: dict, from_pubkey: str, to_pubkey: str) -> Transaction: """ Return a Transaction document - :param dict current_block: Current block infos - :param dict source: Source to send - :param str from_pubkey: Public key of the issuer - :param str to_pubkey: Public key of the receiver + :param current_block: Current block infos + :param source: Source to send + :param from_pubkey: Public key of the issuer + :param to_pubkey: Public key of the receiver :return: Transaction """ @@ -95,8 +89,12 @@ async def main(): """ Main code """ - # connection handler from BMA endpoint - connection = SecuredBMAEndpoint.from_inline(BMAS_ENDPOINT).conn_handler(AIOHTTP_SESSION) + # Create Client from endpoint string in Duniter format + client = Client(BMAS_ENDPOINT) + + # Get the node summary infos to test the connection + response = await client(bma.node.summary) + print(response) # prompt hidden user entry salt = getpass.getpass("Enter your passphrase (salt): ") @@ -111,10 +109,10 @@ async def main(): pubkey_to = input("Enter recipient pubkey: ") # capture current block to get version and currency and blockstamp - current_block = await bma.blockchain.current(connection) + current_block = await client(bma.blockchain.current) # capture sources of account - response = await bma.tx.sources(connection, pubkey_from) + response = await client(bma.tx.sources, pubkey_from) if len(response['sources']) == 0: print("no sources found for account %s" % pubkey_to) @@ -133,17 +131,17 @@ async def main(): transaction.sign([key]) # send the Transaction document to the node - response = await bma.tx.process(connection, transaction.signed_raw()) + response = await client(bma.tx.process, transaction.signed_raw()) if response.status == 200: print(await response.text()) else: print("Error while publishing transaction: {0}".format(await response.text())) - response.close() + # Close client aiohttp session + await client.close() -with AIOHTTP_SESSION: - # Latest duniter-python-api is asynchronous and you have to use asyncio, an asyncio loop and a "as" on the data. - # ( https://docs.python.org/3/library/asyncio.html ) - asyncio.get_event_loop().run_until_complete(main()) +# Latest duniter-python-api is asynchronous and you have to use asyncio, an asyncio loop and a "as" on the data. +# ( https://docs.python.org/3/library/asyncio.html ) +asyncio.get_event_loop().run_until_complete(main()) -- GitLab