Skip to main content

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

Project description

NodePulse Python

[PyPI Package](git branch -M main/)

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
  • Node Types Supported:
    • Hyperion
    • Atomic
    • LightAPI
    • IPFS

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', 'atomic', 'lightapi', or 'ipfs'). 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-1.1.1.tar.gz (7.3 kB view details)

Uploaded Source

Built Distribution

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

nodepulse-1.1.1-py3-none-any.whl (7.4 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for nodepulse-1.1.1.tar.gz
Algorithm Hash digest
SHA256 144991c0ef9a2bf0404fdbb04e64760008d61a9295aa15643c29cd79be4d2a7f
MD5 221fcde9b7d6e3e5c12bc25432341f8e
BLAKE2b-256 59cd8cd9cc42042d455021041a22ab8fca4e839273849303ad429985bf150d1e

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for nodepulse-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f2a6f6e3965415f896ddad764c0ecbb2b30437661bc2d7043e17bbbcfba9824f
MD5 e3cf23a9076b02f26f6895214d25a413
BLAKE2b-256 49cb4673022ea36691f135eb0bfb728e7a725e12bb0b9a41dcd3b58e7686e955

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