Skip to main content

bs-be18000

A Python client and CLI for the ASUS ROG Strix GS-BE18000 router's web API.

Background

This router has no published public API. Like all AsusWRT-powered routers, it exposes the same HTTP(S) JSON API that its own web UI uses to talk to it. The login flow and hook query mechanism below have been confirmed against a real GS-BE18000 (firmware nonce-based login, packet-captured to verify the exact request/response shapes):

  • Login is a nonce/cnonce challenge, not plain base64(user:pass): POST get_Nonce.cgi with {"id": <random>} to get a nonce, then POST login_v2.cgi with login_authorization = sha256("user:nonce:password:cnonce") plus a handful of other form fields. On success the session token comes back as a Set-Cookie: asus_token=... header (not a JSON body) — httpx's cookie jar picks this up automatically.
  • Reading state is GET appGet.cgi?hook=<fn1>(<args1>);<fn2>(<args2>);... — e.g. nvram_get(productid);nvram_get(firmver);get_clientlist();. Confirmed working: nvram_get for NVRAM values and get_clientlist for connected devices. Note nvram_get only ever takes one variable per call — fetching several means chaining several nvram_get(...) calls in one request, not comma-joining variable names into a single call.
  • Settings/actions go through POST applyapp.cgi with rc_service=<name> — this part is still based on general AsusWRT convention rather than a packet capture (we haven't triggered a real settings change to confirm it), so treat run_service/reboot/restart_wireless as less-verified than the read path above.

The handful of high-level convenience methods (get_device_info, get_wan_status, get_clients) use NVRAM keys that are either confirmed above or have been stable across AsusWRT firmware for years, and have been verified end-to-end against a real GS-BE18000. Note that WanStatus.state is the raw wan0_state_t NVRAM code (e.g. "2"), not decoded into a label — cross-reference it against the WAN status shown in the router's own web UI if you need to know what a given code means, since guessing at that mapping risked getting it wrong. If a value comes back empty on your unit, open the router's web UI, watch the Network tab while it loads the relevant page, and adjust the key/hook name accordingly — or just call query_hooks/get_nvram directly with the right name.

Install

For development (installs into the project's own .venv):

uv sync

To use the bs-be18000 CLI as a standalone command from anywhere (installs to ~/.local/bin via uv tool, in editable mode so it tracks source changes):

make install     # or: uv tool install --editable .

Library usage

from bs_be18000 import RouterClient

with RouterClient("192.168.1.1", "admin", "hunter2") as router:
    print(router.get_device_info())
    print(router.get_wan_status())
    for client in router.get_clients():
        print(client)

Escape hatches for anything not wrapped above:

router.get_nvram("wl0_ssid", "wl1_ssid")
router.query_hooks([("nvram_get", "productid"), ("get_clientlist", "")])
router.run_service("restart_qos")

CLI usage

Credentials resolve from flags, then environment variables, then an interactive password prompt — nothing is ever written to disk. Set all three env vars once per shell session and every command below just works, with no re-entering the password each time:

export BS_BE18000_HOST=192.168.1.1
export BS_BE18000_USERNAME=admin
export BS_BE18000_PASSWORD=hunter2   # leading space keeps it out of shell history
                                     # (bash/zsh with HISTCONTROL=ignorespace or
                                     # HIST_IGNORE_SPACE set)

bs-be18000 device info
bs-be18000 wan status
bs-be18000 clients list
bs-be18000 nvram get productid firmver
bs-be18000 system reboot
bs-be18000 --json device info   # machine-readable output

Run bs-be18000 --help or bs-be18000 <command> --help for the full command tree.

Development

uv run pytest       # unit tests, router HTTP calls mocked with respx
uv run ruff check .
uv run mypy src tests

Metadata

Release files for bs-be18000 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bs-be18000 0.1.0
File Size Uploaded Provenance
bs_be18000-0.1.0.tar.gz 30.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for bs-be18000 0.1.0
File Interpreter ABI Platform
bs_be18000-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 42.9 kB

Release files / bs_be18000-0.1.0.tar.gz

Download URL bs_be18000-0.1.0.tar.gz
Size 30.6 kB
Tags Source
SHA-256 checksum
How to use checksums
9d72213ec087b14cf2bd049f39f0253d96d234cc98b690c32bd4a35f3871872c
BLAKE2b-256 checksum
How to use checksums
ce04de6d83f92fa8b93b5af11f322e0968b1571f060b5c87618d2944c284d791
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

Release files / bs_be18000-0.1.0-py3-none-any.whl

Download URL bs_be18000-0.1.0-py3-none-any.whl
Size 12.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a3a35d03ee6bc8710638df681b5d868b368a6cadb9da01e73c4fc76a7934e2d0
BLAKE2b-256 checksum
How to use checksums
fc716ad00e31a2c07e7f5e2d8a3cdaeaf6b3a20b1de60c49ee94db2d07c83121
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

Security for bs-be18000 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for bs_be18000-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page