Remote power management for workstations and servers (iDRAC, iLO, AMT, SSH).
Project description
powerctl
Remote power management library for workstations and servers (iDRAC, iLO, AMT, SSH).
Project Overview
powerctl is a Python library designed to provide a unified interface for controlling the power state of various workstations and servers. It supports multiple protocols through a driver-based architecture, allowing for easy extension via drivers and concurrency via asyncio.
Supported protocols
| Protocol ID | Technology | Notes |
|---|---|---|
idrac |
Dell iDRAC (Redfish) | iDRAC 8 / 9 |
ilo |
HP iLO (Redfish) | iLO 4 / 5 / 6 |
amt |
Intel AMT (WS-Man) | WS-Management SOAP over HTTP(S) |
ssh_linux |
SSH Linux | Uses asyncssh or ssh CLI |
ssh_windows |
SSH / WinRM Windows | PowerShell via SSH or WinRM |
Quick start
Installation
pip install "powerctl[all]" # everything (recommended)
pip install powerctl # core, no optional deps
pip install "powerctl[ssh]" # + asyncssh for SSH drivers
pip install "powerctl[winrm]" # + pywinrm for WinRM driver
import asyncio
from powerctl import PowerClient, Host, Credentials
host = Host(
hostname="192.168.1.10",
protocol="idrac",
credentials=Credentials(username="root", password="calvin"),
)
async def main():
async with PowerClient(host) as client:
result = await client.reboot()
print(result) # <PowerResult action=reboot status=OK ...>
asyncio.run(main())
Per-protocol examples
Dell iDRAC
Host(
hostname="192.168.1.10",
protocol="idrac",
credentials=Credentials(username="root", password="calvin"),
)
HP iLO
Host(
hostname="192.168.1.20",
protocol="ilo",
credentials=Credentials(username="Administrator", password="hunter2"),
)
Intel AMT
Host(
hostname="192.168.1.30",
protocol="amt",
credentials=Credentials(username="admin", password="AMTs3cret!"),
extra={"tls": True}, # use port 16993 (HTTPS)
)
SSH Linux
Host(
hostname="192.168.1.40",
protocol="ssh_linux",
credentials=Credentials(username="sysadmin", private_key_path="/home/me/.ssh/id_ed25519"),
extra={"sudo": True},
)
SSH/WinRM Windows
# Via SSH (OpenSSH Server must be installed on Windows)
Host(
hostname="192.168.1.50",
protocol="ssh_windows",
credentials=Credentials(username="Administrator", password="W1nd0ws!"),
extra={"transport": "ssh"},
)
# Via WinRM (requires pip install powerctl[winrm])
Host(
hostname="192.168.1.50",
protocol="ssh_windows",
credentials=Credentials(username="Administrator", password="W1nd0ws!"),
extra={"transport": "winrm", "https": True},
)
Bulk operations
from powerctl import reboot_all, run_action_all, Host, Credentials
hosts = [
Host(hostname=f"10.0.0.{i}", protocol="idrac",
credentials=Credentials(username="root", password="calvin"))
for i in range(1, 21)
]
async def main():
results = await reboot_all(hosts, max_concurrent=5)
for r in results:
print(r)
Building and development setup
Setup
The project uses setuptools and pyproject.toml.
# Create a virtual environment
python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
# install build tool
pip install --upgrade build
# Install in editable mode with all dependencies
pip install -e ".[all,dev]"
Testing
Tests are located in the tests/ directory and use pytest with pytest-asyncio.
pytest
Linting and Type Checking
The project enforces strict typing and linting standards.
# Linting and formatting
ruff check .
ruff format .
# Type checking
python3 -m pip install types-requests
mypy src/powerctl
Building
python -m build
Writing a custom driver
from powerctl import register_driver, BaseDriver, PowerAction, PowerResult
from powerctl.core import Host
@register_driver
class IpmiDriver(BaseDriver):
"""Example IPMI driver using ipmitool CLI."""
protocol = "ipmi"
async def power_on(self) -> PowerResult:
# call ipmitool here ...
return PowerResult(PowerAction.POWER_ON, success=True)
async def power_off(self) -> PowerResult: ...
async def power_cycle(self) -> PowerResult: ...
async def reboot(self) -> PowerResult: ...
async def shutdown(self) -> PowerResult: ...
Once decorated with @register_driver, the driver is immediately
available to PowerClient by its protocol string.
Running tests
pip install "powerctl[dev]"
pytest
Layout
powerctl/
├── __init__.py # Public API surface
├── client.py # PowerClient facade + bulk helpers
├── core/
│ ├── base.py # BaseDriver ABC, PowerAction enum, PowerResult
│ ├── host.py # Host & Credentials dataclasses
│ ├── registry.py # @register_driver decorator + driver factory
│ └── exceptions.py # Exception hierarchy
└── drivers/
├── _redfish.py # Shared Redfish HTTP helpers
├── idrac.py # Dell iDRAC
├── ilo.py # HP iLO
├── amt.py # Intel AMT
├── ssh_linux.py # SSH Linux
└── ssh_windows.py # SSH / WinRM Windows
Notes:
- Strategy + Registry pattern — drivers are registered by
protocolstring;build_driver(host)picks the right one at runtime. - Abstract Base Class —
BaseDriverenforces the interface;mypy --strictwill catch missing methods. - Zero mandatory dependencies — the stdlib covers iDRAC/iLO/AMT; SSH and WinRM libs are opt-in extras.
- Async-first — all operations are
async, enabling high-throughput bulk management withasyncio.gather. - Dataclasses for config —
HostandCredentialsare frozen.
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 powerctl-0.1.2.tar.gz.
File metadata
- Download URL: powerctl-0.1.2.tar.gz
- Upload date:
- Size: 24.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
037905664c0649df50ab747d7d3c4cf54b34edd0682d8a4899520f42e995a65e
|
|
| MD5 |
e81571714effe1425fe20da398faf8ef
|
|
| BLAKE2b-256 |
aafc5fba029e8146eb6ff230edc832df0ca40f36e6848a350a8f811b88f66a28
|
Provenance
The following attestation bundles were made for powerctl-0.1.2.tar.gz:
Publisher:
publish.yml on diegocortassa/powerctl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
powerctl-0.1.2.tar.gz -
Subject digest:
037905664c0649df50ab747d7d3c4cf54b34edd0682d8a4899520f42e995a65e - Sigstore transparency entry: 1239368414
- Sigstore integration time:
-
Permalink:
diegocortassa/powerctl@6f9005b88434866a39be483866685791274dad54 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/diegocortassa
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6f9005b88434866a39be483866685791274dad54 -
Trigger Event:
push
-
Statement type:
File details
Details for the file powerctl-0.1.2-py3-none-any.whl.
File metadata
- Download URL: powerctl-0.1.2-py3-none-any.whl
- Upload date:
- Size: 28.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73d19ed97d5ec6283c38d3872257418f236d11dccf84e46d20de79ec47d708ad
|
|
| MD5 |
e88fbfc9997f466105154a440f12999e
|
|
| BLAKE2b-256 |
9f7692d958a450ae168b463927cd25400d88662682b5b8008f930edc9165c9f6
|
Provenance
The following attestation bundles were made for powerctl-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on diegocortassa/powerctl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
powerctl-0.1.2-py3-none-any.whl -
Subject digest:
73d19ed97d5ec6283c38d3872257418f236d11dccf84e46d20de79ec47d708ad - Sigstore transparency entry: 1239368418
- Sigstore integration time:
-
Permalink:
diegocortassa/powerctl@6f9005b88434866a39be483866685791274dad54 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/diegocortassa
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6f9005b88434866a39be483866685791274dad54 -
Trigger Event:
push
-
Statement type: