KeeneticPy 📡
Modern, Async/Sync Python Library & CLI for Keenetic Routers (KeeneticOS RCI)
KeeneticPy is an advanced Python package and CLI tool for Keenetic routers powered by KeeneticOS. It provides WireGuard / VPN policy-based routing (Domain & ASN routing), automated CIDR list synchronization, 4G/LTE modem & SMS automation, client bandwidth throttling, Prometheus metrics export, and system monitoring.
✨ Features
- ⚡ Sync & Async Support: Full support for both
Keenetic(synchronous) andAsyncKeenetic(async with), natively compatible with Home Assistant and FastAPI. - 🛡️ Zero Heavy Dependencies: Lightweight and fast architecture built exclusively on
httpxandrich. - 🌐 BGP & Policy-Based Routing (PBR): Route domains via Cloudflare DoH or entire ASN prefixes (via RIPE Stat API) to WireGuard / VPN tunnels in a single call.
- 🔄 Bulk Route Sync: Synchronize static routes directly from URLs or local text files with automatic pruning of obsolete entries (
route sync). - 📶 4G/LTE Modem & SMS Management: Monitor cellular signal quality (RSRP, RSRQ, SINR, Band, Carrier), read incoming SMS, send SMS messages, and execute USSD codes.
- 👥 Client & Bandwidth Controls: Throttle download/upload speeds per MAC, toggle internet access (block/unblock), and configure static DHCP leases.
- 📶 DSL & Mesh Diagnostics: Parse raw VDSL2/ADSL driver stats into readable SNR/attenuation/error tables (
dsl stats,dsl reset), and list Mesh Wi-Fi System (MWS) extender nodes with CPU/RAM/backhaul info (mesh). - 🔄 Live Watch Mode: Add
--watchtohosts,mesh, ordsl statsfor an auto-refreshing terminal dashboard. - 📊 Built-in Prometheus Exporter: Serve real-time system, network traffic, and client metrics for Prometheus and Grafana dashboards (
keenetic exporter). - 💻 Feature-Rich CLI: Manage your router entirely from the terminal.
- 💾 Smart Backup Rotation: Automatically download and rotate timestamped zip archives containing firmware and
startup-config.txt.
🚀 Installation
# Using pip
pip install -U KeeneticPy
# Using uv
uv add KeeneticPy
💻 CLI Usage (Terminal)
The keenetic CLI command is available immediately after installation:
# Display router status, CPU/RAM load, and WAN IPs
keenetic --password "your_password" info
# List connected hotspot clients and real-time traffic (Rx/Tx)
keenetic --password "your_password" hosts
# Show Mesh Wi-Fi System extender nodes (or reboot one by its CID)
keenetic --password "your_password" mesh
keenetic --password "your_password" mesh reboot <cid>
# DSL line diagnostics (SNR, attenuation, error counters), or reset the link
keenetic --password "your_password" dsl stats
keenetic --password "your_password" dsl reset
# Live-refreshing dashboard (works with hosts / mesh / dsl stats)
keenetic --password "your_password" hosts --watch --interval 5
# Route a domain to WireGuard VPN
keenetic --password "your_password" route add-domain discord.com --interface Wireguard0
# Route Cloudflare ASN (13335) IP prefixes to WireGuard
keenetic --password "your_password" route add-asn 13335 --interface Wireguard0
# Synchronize routes from remote URL or local file (auto-prunes stale routes)
keenetic --password "your_password" route sync https://antifilter.download/list/allyouneed.lst --interface Wireguard0
# Set device bandwidth limit (5 Mbps down, 1 Mbps up)
keenetic --password "your_password" client limit AA:BB:CC:DD:EE:FF --rx 5000 --tx 1000
# Block / unblock device internet access
keenetic --password "your_password" client block AA:BB:CC:DD:EE:FF
keenetic --password "your_password" client unblock AA:BB:CC:DD:EE:FF
# Assign static DHCP lease
keenetic --password "your_password" client bind AA:BB:CC:DD:EE:FF 192.168.1.100 -n "Desktop-PC"
# 4G/LTE modem signal diagnostics & SMS
keenetic --password "your_password" modem status
keenetic --password "your_password" modem sms-list
keenetic --password "your_password" modem sms-send +1234567890 "Server alert"
keenetic --password "your_password" modem ussd "*100#"
# Run standalone Prometheus metrics exporter on port 9100
keenetic --password "your_password" exporter --port 9100
# Download router backup (firmware + config)
keenetic --password "your_password" backup --keep 5
# Reboot router remotely
keenetic --password "your_password" reboot
Tip: Avoid passing credentials in CLI arguments by setting environment variables:
export KEENETIC_USER="admin" export KEENETIC_PASSWORD="your_router_password" export KEENETIC_PANEL="http://192.168.1.1"
📝 Python Usage
1. Synchronous Client (Keenetic)
from KeeneticPy import Keenetic, set_speed_limit, set_client_access, get_modem_info, send_sms
with Keenetic(user="admin", password="password", panel="http://192.168.1.1") as router:
# System details
print("Version:", router.version())
print("WAN IP:", router.global_ip())
# Add domain route to WireGuard
router.add_route_with_domain("discord.com", interface="Wireguard0")
# Set 10 Mbps bandwidth limit for a phone
set_speed_limit(router, "aa:bb:cc:dd:ee:ff", rx_kbps=10000, tx_kbps=5000)
# Check 4G/LTE signal strength
modem = get_modem_info(router)
print("Cellular Operator:", modem.get("operator"))
print("RSRP Signal:", modem.get("rsrp"))
# Send SMS notification
send_sms(router, "+1234567890", "Router backup completed successfully.")
# Create backup
router.backup(max_backups=3)
2. Asynchronous Client (AsyncKeenetic - Home Assistant / FastAPI)
import asyncio
from KeeneticPy import AsyncKeenetic, sync_static_routes, parse_route_entries, fetch_route_text
async def main():
async with AsyncKeenetic(user="admin", password="password", panel="http://192.168.1.1") as router:
hosts = await router.hosts()
print("Connected clients count:", len(hosts.get("host", [])))
# Sync remote IP list to Wireguard
raw_routes = fetch_route_text("https://example.com/routes.txt")
entries = parse_route_entries(raw_routes)
result = await sync_static_routes(router, entries, interface="Wireguard0")
print("Sync result:", result)
asyncio.run(main())
3. BGP & DNS Lookup Utilities (BGPTools)
from KeeneticPy import domain2ip, asn2cidr, cidr2mask, mask2cidr
# Resolve domain via Cloudflare DoH and collapse to CIDR subnets
result = domain2ip("github.com")
print("IPs:", result["ipler"])
print("Subnets:", result["subnetler"])
# Fetch IPv4 announced prefixes from official RIPE Stat API
cloudflare = asn2cidr(13335)
print("Company:", cloudflare["company"])
print("Prefixes count:", len(cloudflare["prefixes"]))
# Subnet conversions
print(cidr2mask("192.168.1.0/24")) # 255.255.255.0
print(mask2cidr("255.255.255.0")) # 24
💸 Sponsor & Support
🌐 Copyright and License
- Copyright (C) 2023 - 2026 by keyiflerolsun ❤️️
- Licensed under the terms of the GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007.
♻️ Contact
Feel free to reach out via Telegram; @keyiflerolsun
Written for @KekikAkademi
Metadata
Release files for KeeneticPy 3.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| keeneticpy-3.0.1.tar.gz | 52.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| keeneticpy-3.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 94.2 kB
Release files / keeneticpy-3.0.1.tar.gz
| Download URL | keeneticpy-3.0.1.tar.gz |
|---|---|
| Size | 52.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d13fcd832afeaa274e5b3093047ca32b268464897b8751926778bd5fbc46c11f
|
|
BLAKE2b-256 checksum How to use checksums |
9697f25d90bde51054ba6a82e69b03fabc60f596b594020c08af48f8dc6bdf65
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / keeneticpy-3.0.1-py3-none-any.whl
| Download URL | keeneticpy-3.0.1-py3-none-any.whl |
|---|---|
| Size | 41.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8e871ef444f25d94f39b74a42a1b41ad4782e02c207122913acd253690ba5161
|
|
BLAKE2b-256 checksum How to use checksums |
53db28f517b3477ce4fb7546f9e36b4fc5af51f0f6df1673594c2c5817f13399
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|