Metadata-Version: 2.5
Name: skale-watchdog-client
Version: 4.1.0.dev0
Summary: SKALE Watchdog Client - SKALE and FAIR Nodes Health Checks
Project-URL: Homepage, https://github.com/skalenetwork/skale-watchdog
Author-email: SKALE Labs <support@skalelabs.com>
License-Expression: AGPL-3.0-or-later
License-File: LICENSE
Keywords: skale
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: <4,>=3.13
Requires-Dist: requests>=2.33.0
Description-Content-Type: text/markdown

# SKALE Watchdog Client

[![Discord](https://img.shields.io/discord/534485763354787851.svg)](https://discord.gg/vvUtWJB)

Minimal Python client for interacting with SKALE Watchdog node APIs (SKALE + FAIR).

## Install

```bash
pip install skale-watchdog-client
```

Supports Python 3.13+.

## Quick Start

```python
from watchdog_client import SkaleNode, SkalePassiveNode, FairNode, FairPassiveNode

# Base URL can be domain name or IP address of the node.
# A bare host or http:// URL gets :3009, https:// gets :311. An explicit port always wins.
skale_node = SkaleNode('my-skale-node.example.com')
# Use SkalePassiveNode for SKALE nodes running in passive mode
skale_passive = SkalePassiveNode('my-passive-skale-node.example.com')

fair_node = FairNode('my-fair-node.example.com')
# Use FairPassiveNode for FAIR nodes running in passive mode (no SGX endpoint)
fair_passive = FairPassiveNode('my-passive-fair-node.example.com')

# Call any endpoint: each returns ApiResult (fields: data, error, status_code, cache_age, stale)
# cache_age is seconds since the node cached the value, or None when it was fetched live.
# Pass max_age=360 to the node: any result older than that is stale and falsy.
r = skale_node.public_ip()
if r:
    print('Public IP:', r.data)
else:
    print('Error:', r.error)

# Execute every available check on a node
results = skale_node.all_checks()
for name, res in results.items():
    print(name, 'OK' if res else f'ERR: {res.error}')
```

## API

### Common (available on both SkaleNode and FairNode)

* containers
* sgx (not available on passive nodes)
* hardware
* endpoint
* meta\_info (maps to /meta-info)
* btrfs
* ssl
* check\_report (maps to /check-report)

### SKALE-specific (`SkaleNode`)

* schains
* ima
* schain\_containers\_versions (maps to /schain-containers-versions)
* public\_ip (maps to /public-ip)
* validator\_nodes (maps to /validator-nodes)

### SKALE Passive (`SkalePassiveNode`)

Same as `SkaleNode`, except the following checks return an error (404), because they are not available on SKALE passive nodes:

* sgx
* schains
* ima
* validator\_nodes

### FAIR-specific (`FairNode`)

* chain\_checks (maps to /chain-checks)
* chain\_record (maps to /chain-record)

### FAIR Passive (`FairPassiveNode`)

Same as `FairNode`, except:

* sgx: returns an error ApiResult: "SGX check is not available on FAIR passive nodes"

### Batch execution

Call `all_checks()` on any node instance to execute each public check method (no params) and get a dict mapping method name to its ApiResult. One failing check does not stop others.

## Result Object

```python
res = fair_node.chain_checks()
if res:
    print(res.data)
else:
    raise RuntimeError(res.error)
```

### License

![GitHub](https://img.shields.io/github/license/skalenetwork/skale-watchdog.svg)

All contributions are made under the [GNU Affero General Public License v3](https://www.gnu.org/licenses/agpl-3.0.en.html). See [LICENSE](LICENSE).
