Package: exonum-python-client
Exonum Python Light ClientPython client for theExonum Framework.OverviewExonum Light Client is a Python library for working with Exonum blockchain
from the client side. It can be easily integrated to an existing
application. Also, Exonum Light Client provides access to common utils
toolkit which contains some helpful functions for hashing, cryptography,
serialization, etc.CapabilitiesBy using the client you are able to perform the following operations:Submit transactions to the nodeReceive information on transactionsReceive information on blockchain blocksReceive information on the node systemReceive information on the node statusCompatibilityThe following table shows versions compatibility:Light ClientExonum0.10.9.*0.20.10.*0.3.10.12.*1.0.x1.0.*masterexonummaster branchSystem DependenciesPython 3.5 or above.Package installer for Python3 (pip3)ExamplesThe following example shows how to create an instance of the Exonum client
which will be able to work with an Exonum node with the
Cryptocurrency Advanced service mounted on it, athttp://localhost:8080address:Installing Python Light ClientFirst of all we need to install our client library:gitclonegit@github.com:exonum/exonum-python-client.git
pip3install-eexonum-python-client--no-binary=protobufExonum Client Initializationfromexonum_clientimportExonumClient,ModuleManager,MessageGeneratorfromexonum_client.cryptoimportKeyPairclient=ExonumClient(hostname="localhost",public_api_port=8080,private_api_port=8081,ssl=False)Compiling Proto FilesTo compile proto files into the Python analogues we need a protobuf loader:withclient.protobuf_loader()asloader:#  Your code goes here.Since loader acquires resources on initialization, creating via context manager is recommended.
Otherwise you should initialize and deinitialize client manually:loader=client.protobuf_loader()loader.initialize()# ... Some usageloader.deinitialize()Then we need to run the following code:loader.load_main_proto_files()# Load and compile main proto files, such as `runtime.proto`, `consensus.proto`, etc.loader.load_service_proto_files(runtime_id=0,service_name='exonum-supervisor:1.0.0')# Same for specific service.runtime_id=0 here means, that service works in Rust runtime.Creating Transaction MessagesThe following example shows how to create a transaction message:alice_keys=KeyPair.generate()cryptocurrency_artifact_name="exonum-cryptocurrency-advanced"cryptocurrency_artifact_version="1.0.0"loader.load_service_proto_files(runtime_id=0,artifact_name=cryptocurrency_artifact_name,artifact_version=cryptocurrency_artifact_version)cryptocurrency_module=ModuleManager.import_service_module(cryptocurrency_artifact_name,cryptocurrency_artifact_version,"service")cryptocurrency_message_generator=MessageGenerator(instance_id=1024,artifact_name=cryptocurrency_artifact_name,artifact_version=cryptocurrency_artifact_version)create_wallet_alice=cryptocurrency_module.CreateWallet()create_wallet_alice.name='Alice'create_wallet_alice_tx=cryptocurrency_message_generator.create_message(create_wallet_alice)create_wallet_alice_tx.sign(alice_keys)1024 - service instance ID.alice_keys - public and private keys of the ed25519 public-key signature
system.After invoking the sign method, we get a signed transaction.
This transaction is ready for sending to the Exonum node.Sending Transaction to the Exonum NodeAfter successfully sending the message, we'll get a response which will
contain a hash of the transaction:response=client.public_api.send_transaction(create_wallet_alice_tx){"tx_hash":"3541201bb7f367b802d089d8765cc7de3b7dfc253b12330b8974268572c54c01"}Subscribing to eventsIf you want to subscribe to events (subscription_type: "transactions" or "blocks"), use the following code:withclient.create_subscriber(subscription_type="blocks")assubscriber:subscriber.wait_for_new_event()subscriber.wait_for_new_event()Context manager will automatically create a connection and will disconnect after use.
Or you can manually do the same:subscriber=client.create_subscriber(subscription_type="blocks")subscriber.connect()# ... Your codesubscriber.stop()Keep in mind that if you forget to stop the subscriber, you may discover HTTP
errors when you try to use Exonum API.Getting Data on the Available Servicesclient.public_api.available_services().json()The code will show a list of the artifacts available for the start and a list of
working services:{"artifacts":[{"runtime_id":0,"name":"exonum-supervisor","version":"1.0.0"},{"runtime_id":0,"name":"exonum-explorer-service","version":"1.0.0"}],"services":[{"spec":{"id":2,"name":"explorer","artifact":{"runtime_id":0,"name":"exonum-explorer-service","version":"1.0.0"}},"status":"Active","pending_status":null},{"spec":{"id":0,"name":"supervisor","artifact":{"runtime_id":0,"name":"exonum-supervisor","version":"1.0.0"}},"status":"Active","pending_status":null}]}More ExamplesTo see more examples and find out how to work with proofs gohere.Also you can find the sample scripts at theexamplessection.TestingTo run tests, use the following command:python3-munittestContributingYou can see notes for developers in theContribution Guidepage.Known ProblemsIf within use you discover the following error:TypeError:Couldn'tbuildprotofileintodescriptorpool!It is due to the issue with Protobuf binary wheels. The only work around is to
install the pure Python implementation.pipuninstallprotobuf
pipinstall--no-binary=protobufprotobufLicenseApache 2.0 - seeLICENSEfor more information.