Skip to main content

A Python library to maintain and utilize a list of healthy nodes

Project description

NodePulse Python

PyPI Package

Maintain and utilize a list of healthy nodes.

Get Started | Examples

NodePulse is a lightweight Python library designed to help developers maintain and utilize a list of healthy nodes (Currently it supports Hyperion and Atomic API nodes). The library connects to a Cloudflare Load Balanced API https://nodes.nodepulse.co/nodes (Which in turn connects to 3 backend APIs running on different cloud platforms) that provides a list of healthy nodes, which it regularly refreshes, and falls back to a predefined list of default nodes in case of not being able to contact any of the backends.

For now only the WAX network is supported.

Features

  • GeoIP Integration: Automatically connects you to geographically closest nodes
  • Real-time Node Discovery: Dynamically finds and connects to available nodes
  • Fault Tolerance: Maintains network integrity even if some nodes fail
  • Custom Default Nodes: Allows overriding of default nodes for specific node types and networks
  • Network Supported: WAX

Get Started

Install the package

pip install nodepulse

Basic Example

By default, it will provide you with 3 healthy Hyperion Mainnet nodes. To choose atomic and/or testnet nodes, you need to use custom options.

from nodepulse import NodePulse

# Initialize NodePulse with default options
node_pulse = NodePulse()

# Retrieve the next healthy node in the list
node = node_pulse.get_node()
print(f"Using node: {node}")

Custom Options

You can customize the behavior of NodePulse by passing options when creating an instance. Available options include:

  • node_type: Type of nodes to use ('hyperion' or 'atomic'). Default is 'hyperion'
  • network: Network to use ('mainnet' or 'testnet'). Default is 'mainnet'
  • node_count: Number of nodes to retrieve from the API. Default is 3
  • update_interval: How often (in milliseconds) to refresh the node list. Default is 30000
  • api_url: The API URL to fetch healthy nodes. Default is 'https://nodes.nodepulse.co/nodes'
  • default_nodes: Custom default nodes to use as fallback
  • history_full: (Hyperion only) Whether to return nodes with full history. Default is True
  • streaming_enabled: (Hyperion only) Whether to return nodes with streaming enabled. Default is True
  • atomic_assets: (Atomic only) Whether to return nodes with atomicassets support. Default is True
  • atomic_market: (Atomic only) Whether to return nodes with atomicmarket support. Default is True
  • use_qry_hub: Whether to use QryHub for fetching nodes. Default is False
  • qry_hub_api_url: Custom QryHub API URL (optional, only used if use_qry_hub is True)
  • chain_id: The chain ID to use when fetching nodes from QryHub (required if use_qry_hub is True)

Example of using custom options with default node override for Hyperion Mainnet:

from nodepulse import NodePulse

custom_default_nodes = {
    'hyperion': {
        'mainnet': [
            'https://wax.eosrio.io',
            'https://api.waxsweden.org',
            'https://wax.eu.eosamsterdam.net'
        ]
    }
}

# Initialize with custom options and default nodes
node_pulse = NodePulse(
    node_type='hyperion',
    network='mainnet',
    node_count=5,
    update_interval=60000,  # Refresh every minute
    api_url='https://nodes.nodepulse.co/nodes',
    default_nodes=custom_default_nodes,
    history_full=False,
    streaming_enabled=False
)

# Retrieve a node from the custom configuration
node = node_pulse.get_node()
print(f"Using node: {node}")

Example of using custom options with default node override for Atomic Mainnet:

from nodepulse import NodePulse

# Initialize with custom options
node_pulse = NodePulse(
    node_type='atomic',
    network='mainnet',
    node_count=5,
    update_interval=60000,  # Refresh every minute
    api_url='https://nodes.nodepulse.co/nodes',
    atomic_assets=False,
    atomic_market=False
)

# Retrieve a node from the custom configuration
node = node_pulse.get_node()
print(f"Using node: {node}")

Example of using QryHub to fetch Hyperion nodes for the Jungle testnet:

from nodepulse import NodePulse

node_pulse = NodePulse(
    use_qry_hub=True,
    chain_id='73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d',
    node_type='hyperion',
    node_count=3,
    history_full=True,
    streaming_enabled=True
)

node = node_pulse.get_node()
print(f"Using QryHub node: {node}")

Event Hooks

NodePulse provides several event hooks that allow developers to react to various events during the node-fetching process:

on_node_update(nodes)

This hook is triggered every time the node list is successfully updated:

def on_node_update(nodes):
    print(f"Nodes updated: {nodes}")

node_pulse = NodePulse(on_node_update=on_node_update)

on_error(error)

This hook is called whenever there is an error while fetching nodes:

def on_error(error):
    print(f"Error occurred: {str(error)}")

node_pulse = NodePulse(on_error=on_error)

on_fallback(fallback_type, nodes)

This hook is triggered when falling back to existing or default nodes:

def on_fallback(fallback_type, nodes):
    print(f"Falling back to {fallback_type} nodes: {nodes}")

node_pulse = NodePulse(on_fallback=on_fallback)

Logging Options

NodePulse provides flexible logging options to help you debug and monitor its operation:

import logging

# Create custom logger
custom_logger = logging.getLogger("custom_logger")
custom_logger.setLevel(logging.INFO)

# Initialize with custom logger and log level
node_pulse = NodePulse(
    logger=custom_logger,
    log_level='info'
)

Available log levels:

  • error
  • warn
  • info
  • debug

Default Nodes

If the API fails to return healthy nodes or an error occurs, NodePulse falls back to a predefined list of default nodes:

DEFAULT_NODES = {
    'hyperion': {
        'mainnet': [
            'https://wax.eosusa.news',
            'https://wax.greymass.com',
            'https://wax.cryptolions.io',
        ],
        'testnet': [
            'https://testnet.waxsweden.org',
            'https://testnet.wax.pink.gg',
            'https://testnet.wax.eosdetroit.io',
        ],
    },
    'atomic': {
        'mainnet': [
            'https://wax.api.atomicassets.io',
            'https://aa.wax.blacklusion.io',
            'https://wax-aa.eu.eosamsterdam.net',
        ],
        'testnet': [
            'https://test.wax.api.atomicassets.io',
            'https://atomic-wax-testnet.eosphere.io',
            'https://testatomic.waxsweden.org',
        ],
    },
}

Error Handling and Retries

If fetching nodes from the API fails, NodePulse will attempt to use existing nodes or fall back to default nodes. The library uses Python's built-in threading for background updates and proper error handling.

Thread Safety

NodePulse is thread-safe and can be safely used in multi-threaded applications. It uses Python's threading module for background updates and proper locking mechanisms for shared state.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nodepulse-0.1.0.tar.gz (7.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nodepulse-0.1.0-py3-none-any.whl (7.2 kB view details)

Uploaded Python 3

File details

Details for the file nodepulse-0.1.0.tar.gz.

File metadata

  • Download URL: nodepulse-0.1.0.tar.gz
  • Upload date:
  • Size: 7.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.11.2

File hashes

Hashes for nodepulse-0.1.0.tar.gz
Algorithm Hash digest
SHA256 4b5b66a56bec55634ed3c10d5855bd630ed1facd59eda2e27b2290d804d6acc0
MD5 06de25af3cf9d9000bb45821887525de
BLAKE2b-256 2eccd1fba4be3a5f1d7e3e0ac605b3e00c5f620ef1c05a0c0f9ff15246964b14

See more details on using hashes here.

File details

Details for the file nodepulse-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: nodepulse-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.11.2

File hashes

Hashes for nodepulse-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 45b58956f075f521909ddb2f0f265654e1de1ab01cf2e883faae8e271d5b285e
MD5 4fc6e25edd03832789d63bca258aa24f
BLAKE2b-256 3889484d81a89c50335631239a222a95e73cb1e652a473bf25863ecaf827c15c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page