Skip to main content

Snakeskin

Python + Fabric == snakeskin

This library is a re-implementation of the official Hyperledger Fabric (HLF) Python SDK, providing simpler Python interfaces with HLF while still allowing for fine-grained control over communication with your network.

Specifically, we are building this library with the following goals in mind:

  • Clear configuration - offer configuration that is clearly documented, easy to use, and free of redundancies
  • Simplicity - offer simple, high-level interfaces for use with less complex networks
  • Control - offer fine-grained communication interfaces for interaction with the network, that are as clearly documented as their higher-level counterparts
  • Stateless - where feasible, avoid the complexities of managing state transitions, allowing for a more reliable development experience
  • Fail gracefully - raise semantic, hierarchical, and meaningful error messages
  • Pythonic - use Python naming conventions to allow for cleaner integration into your Python app

With snakeskin you can manage transaction life-cycles, request retries, and complex network gateways with a high degree of specificity and control, while still leveraging higher-level operations when the control is not needed or desired.

Installation

$ [sudo] pip install snakeskin-fabric

Config

Snakeskin can be configured using a static file, or dynamically in Python, and is relatively flexible, as the requirements for a configuration depend largely on the use case.

See the example configuration in examples/config-files/example-blockchain-config.yaml for example configuration structure. Note that the following file formats are supported:

  • YAML - (.yaml, .yml)
  • JSON - (.json)

To load a configuration into the framework, simply do:

from snakeskin.config import BlockchainConfig

# Or load from a static file
blockchain = BlockchainConfig.from_file('/path/to/config/file.yaml')

# Or load from a dictionary
blockchain = BlockchainConfig.from_dict({
    # ...
})

Interacting with the Blockchain

To run transactions against the blockchain, it's easiest to use a Gateway, which is pre-configured with the requisite peers, orderers, channel, and chaincode specification. See the gateways section of the example config for configuration options. Once configured, you can retrieve your gateway from the blockchain config with:

gateway = blockchain.get_gateway('my-gateway')

# or build your own programatically:
from snakeskin.models.gateway import Gateway
gateway = Gateway(
    # ...
)

Transactions

Once configured, performing transactions against the chaincode is relatively straight-forward. Gateways expose the same high-level abstractions - invoke and query - as the HLF peer CLI command.

# query the chaincode to retrieve data
transaction = await gateway.query(
    fcn='doSomething',
    args=['arg1', 'arg2']
)

# invoke the chaincode to persist data, waiting for the chaincode to
# successfully commit
transaction = await gateway.invoke(
    fcn='doSomething',
    args=['arg1', 'arg2'],
    timeout=50
)

transaction.response_payload #=> b'<chaincode response>'

However, if you want more control over the transaction flow, you can use the transact method and chain operations (see snakeskin.models.GatewayTXBuilder for available options):

# A step-by-step transaction flow
transaction = await (
    gateway.transact(
        fcn='doSomething',
        args=['arg1', 'arg2']
    )
    # Sends the transaction to the peers for endorsement
    .propose()
    # Optionally sends the transaction to the orderers for committing
    .submit()
    # Optionally wait (up to 50 seconds) for the transaction to be successfully
    # committed to the peer
    .wait_for_commit(timeout=50)
)

transaction.response_payload #=> b'<chaincode response>'

Network Administration

Most administrative operations are also available through the Gateway:

# Creates the channel, via the orderer
await gateway.create_channel(tx_file_path='/path/to/channel.tx')
# Joins the gateway's endorsing peers to the channel
await gateway.join_channel()
# Query instantiated chaincode for the channel
resp = await gateway.query_instantiated_chaincodes()
resp.chaincodes[0].name # => 'my-chaincode'
# Installs the chaincode
await gateway.install_chaincode()
# Instantiates the chaincode
await gateway.instantiate_chaincode(timeout=60)
# Upgrades the chaincode
await gateway.instantiate_chaincode(timeout=60, upgrade=True)

Note that not all assets on the Gateway are required for each administrative operation. create_channel, for instance, doesn't require any endorsing peers defined on the Gateway.

Standalone Operations

A Gateway definition is not required to perform any operation against the blockchain, it is simply a helpful tool in configuring groupings of assets. To perform operations without a Gateway, import them from the snakeskin.operations module. For example:

from snakeskin.operations import create_channel

await create_channel(
    requestor=config.get_user('my-user'),
    orderers=[config.get_orderer('my-orderer')],
    channel=config.get_channel('my-channel'),
    tx_file_path='/path/to/channel.tx'
)

Similarly, fine-grained transaction management is available from snakeskin.transact:

from snakeskin.transact import (
    generate_cc_tx, propose_tx, commit_tx, raise_tx_proposal_error
)

requestor = config.get_user('my-user')

# Generate a new chaincode transaction against mycc on my-channel
generated_tx = await generate_cc_tx(
    requestor=requestor,
    cc_name=config.get_chaincode('mycc').name,
    channel=config.get_channel('my-channel'),
    fcn='doSomething',
    args=['arg1', 'arg2']
)

# Send the proposal to my-peer
endorsed_tx = await propose_tx(
    peers=[config.get_peer('my-peer')],
    generated_tx=generated_tx
)

# Raise errors on endorsement failure
raise_tx_proposal_error(
    endorsed_tx,
    'Endorsements failed for '
)


# Commit the transaction via the orderer
committed_transaction = await commit_tx(
    requestor=requestor,
    orderers=[config.get_orderer('my-orderer')],
    endorsed_tx=endorsed_tx,
)

Events

To stream blocks from a Peer or Orderer node, use the snakeskin.events module, as such:

from snakeskin.events import PeerEvents

events = PeerEvents(
    requestor=requestor,
    channel=config.get('my-channel'),
    peer=config.get('my-peer')
)

stream = events.stream_blocks(
    start=0, # start at block 0
    stop=10 # end at block 10 (if omitted, will stream forever)
)
async for raw_block in stream:
    block = raw_block.decode()
    for transaction in block.transactions:
        transaction.tx_id # => '1234567'

To stream filtered blocks, from the peer, use snakeskin.events.PeerFilteredEvents, and to stream blocks from the orderer use snakeskin.events.OrdererEvents. All of these classes implement similar interfaces.

Contributing

Coming soon

License

This software uses the Apache License Version 2.0 software license.

Metadata

Release files for snakeskin-fabric 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for snakeskin-fabric 0.1.1
File Size Uploaded
snakeskin-fabric-0.1.1.tar.gz 93.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for snakeskin-fabric 0.1.1
File Interpreter ABI Platform
snakeskin_fabric-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 244.4 kB

Release files / snakeskin-fabric-0.1.1.tar.gz

Download URL snakeskin-fabric-0.1.1.tar.gz
Size 93.2 kB
Tags Source
SHA-256 checksum
How to use checksums
e8295a040ccad07cb55fd4c522a63e2e5b6193b7249b1fb09f315430864da705
BLAKE2b-256 checksum
How to use checksums
d73853ec562c3b2467bb053accf19fcf9579c96a961178d95c057094ca1e0ed8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3

Release files / snakeskin_fabric-0.1.1-py3-none-any.whl

Download URL snakeskin_fabric-0.1.1-py3-none-any.whl
Size 151.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
be70a432dabae48d9341932373b0b13127124e4ff1ccc54a5c41a218f631b458
BLAKE2b-256 checksum
How to use checksums
f061a83e8f51f8f3d386b84a8eab228d0ab53a9c0a585f30ecf2cd70a501d309
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page