A Python library to maintain and utilize a list of healthy nodes
Project description
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 3update_interval: How often (in milliseconds) to refresh the node list. Default is 30000api_url: The API URL to fetch healthy nodes. Default is 'https://nodes.nodepulse.co/nodes'default_nodes: Custom default nodes to use as fallbackhistory_full: (Hyperion only) Whether to return nodes with full history. Default is Truestreaming_enabled: (Hyperion only) Whether to return nodes with streaming enabled. Default is Trueatomic_assets: (Atomic only) Whether to return nodes with atomicassets support. Default is Trueatomic_market: (Atomic only) Whether to return nodes with atomicmarket support. Default is Trueuse_qry_hub: Whether to use QryHub for fetching nodes. Default is Falseqry_hub_api_url: Custom QryHub API URL (optional, only used ifuse_qry_hubis True)chain_id: The chain ID to use when fetching nodes from QryHub (required ifuse_qry_hubis 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b5b66a56bec55634ed3c10d5855bd630ed1facd59eda2e27b2290d804d6acc0
|
|
| MD5 |
06de25af3cf9d9000bb45821887525de
|
|
| BLAKE2b-256 |
2eccd1fba4be3a5f1d7e3e0ac605b3e00c5f620ef1c05a0c0f9ff15246964b14
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45b58956f075f521909ddb2f0f265654e1de1ab01cf2e883faae8e271d5b285e
|
|
| MD5 |
4fc6e25edd03832789d63bca258aa24f
|
|
| BLAKE2b-256 |
3889484d81a89c50335631239a222a95e73cb1e652a473bf25863ecaf827c15c
|