ReadyView Dashboard Python Library
The ReadyView Dashboard Python library provides all current ReadyView dashboard API calls to interface with the ReadyLinks ReadyView cloud-managed platform. ReadyView generates the library based on dashboard API's OpenAPI spec to keep it up to date with the latest API releases, and provides the full source code for the library including the tools used to generate the library. ReadyLinks welcomes constructive pull requests that maintain backwards compatibility with prior versions. The library requires Python 3.8+, receives support from the community, and you can install it via PyPI:
pip install --upgrade readyview
Usage
- Export your Organization ID and API Key as an environment variable, for example:
export READYVIEW_DASHBOARD_ORG_ID=YOUR_ORG_ID
export READYVIEW_DASHBOARD_API_KEY=YOUR_API_KEY
- Import the library with a single line at the top of your Python script.
import readyview
- Instantiate the dashboard client.
dashboard = readyview.Dashboard()
- Start programmatically interacting with your ReadyView dashboard!
my_networks = dashboard.network.get_networks()
Errors and strict mode
By default, a call that fails returns None, so existing scripts keep working. To find out why a call failed, turn on strict mode:
import readyview
dashboard = readyview.Dashboard(raise_errors=True)
try:
config = dashboard.switch.get_switch_configurations("AA:BB:CC:DD:EE:FF")
except readyview.ReadyViewAPIError as error:
print(error)
# GET /v1/devices/AA:BB:CC:DD:EE:FF/switch failed with HTTP 504: The device did not answer within the time limit.
In strict mode, a call that fails raises readyview.ReadyViewAPIError, which has:
status_code: the HTTP status, such as 401, 404, 429 or 504. It isNonewhen no reply arrived, because the API could not be reached or did not answer in time. Those calls raise the subclassreadyview.ReadyViewConnectionError.message: why the call failed, as the API explained it.methodandpath: the call that failed, such asGETand/v1/devices/AA:BB:CC:DD:EE:FF/switch.retry_after: when the reply has aRetry-Afterheader (usually with a 429, when you are rate limited), how many seconds it asks you to wait before trying again. OtherwiseNone.
The error is built from the API's reply only. It never repeats what you sent, or the values the API rejected, since those can be passwords.
Calls that work return the same values in both modes, with two differences in strict mode: any 2xx status counts as success, and a reply that is not JSON (say, a hotel network's sign-in page) raises ReadyViewAPIError.
Logging
The library logs to the readyview logger with Python's logging module. It logs each reply at DEBUG. In the default mode, it also logs a failed call: an error status at INFO, and a request that got no reply at WARNING, which earlier versions printed. To see why calls return None without switching to strict mode:
import logging
logging.basicConfig()
logging.getLogger("readyview").setLevel(logging.INFO)
SNMPv3 users
SnmpV3User builds a user that a switch accepts. It checks the firmware's rules as it is built: a name of 3-16 characters, passwords of 9-15, printable ASCII without spaces, ' or \. dashboard.switch.add_snmp_user() then adds it safely:
import readyview
from readyview import SnmpV3User
dashboard = readyview.Dashboard()
user = SnmpV3User.auth_priv("nms-poller", auth_password="...", privacy_password="...")
for device in dashboard.network.get_devices("YOUR-NETWORK-ID"):
if device["device_type"] == "Switch" and device["status"] == "Online":
result = dashboard.switch.add_snmp_user(device["mac_address"], user)
print(device["name"], result.status.value, result.detail)
For each switch, add_snmp_user:
- reads the switch first, and leaves it alone if it already has the user, so it is safe to run again
- reports a
conflictwhen the name exists with other settings, since the API can add an SNMPv3 user but cannot change or delete one - reports
fullwhen the switch already has 10 users - turns the SNMP service on if it is off
- checks the reply for refused values, then reads the configuration back until the switch reports the user, the only real confirmation
It never raises for a switch it could not configure: result.status, result.detail and result.ok say what happened. Its live configuration reads are spaced to stay under the API's limit of 30 a minute. SnmpV3User.auth_no_priv() and SnmpV3User.no_auth_no_priv() build the other security levels, and dashboard.switch.get_snmp_users(mac) lists a switch's users without their passwords.
Automation
Operations that report an outcome
These dashboard.switch methods each make one change and return an Outcome:
ok: whether the switch ends up as askedstatus: what happened, such assent,refused,up to dateorerrordetail: the API's reason, or what changed
They never raise for a switch they could not change, so a loop over many switches reports every one:
| Method | What it does |
|---|---|
apply_settings(mac, change) |
Sends a SwitchPost change and reports any value the switch refused |
use_template(mac, template_id) |
Applies a configuration template; reports skipped when the template is for another model |
upgrade_firmware(mac, version=None, channel=None) |
Starts an upgrade; reports up to date when the switch already has the firmware |
add_bandwidth_profiles(mac, profiles) |
Adds bandwidth profiles, or replaces those with the same ids |
bind_bandwidth_profile(mac, client_mac, profile_id) |
Finds the client's port and limits the client to a profile |
update_client(mac, client_mac, **fields) |
Changes a connected client, e.g. location="Room 101" |
add_snmp_user(mac, user) |
Adds an SNMPv3 user (see above) |
Scripts that change many switches
readyview.automation holds the parts every automation script repeats. That is the --network / --switch / --dry-run / --yes command line, plus picking the online switches, with a firmware minimum if you set one. It shows the plan, asks before changing anything, reports each switch, and ends with a summary and an exit status. A complete script:
from readyview import automation
from readyview.switch_post import Lldp, SwitchPost
parser = automation.command_line("Turn LLDP on.")
args = parser.parse_args()
change = SwitchPost(lldp=Lldp(enabled=True))
raise SystemExit(automation.run(
args, "turn LLDP on",
lambda dashboard, switch: dashboard.switch.apply_settings(switch["mac_address"], change),
min_firmware=7.655,
))
automation.ask_secret(label, env_var) reads a password from the environment, or has it typed twice at a hidden prompt.
Reports
readyview.reports.gather(dashboard, switches) reads every switch's ports and recent metrics from ReadyView's cache, several at a time. A switch that cannot be read is listed with the reason. device_rows(), client_rows(), fiber_rows() and firmware_rows() turn that into report rows, and find_device(mac, ...) finds where a device is connected. The rows are plain dicts, ready for pandas:
import pandas as pd
from readyview import reports
switches = dashboard.device.get_devices(params={"device_type": ["Switch"]})
data = reports.gather(dashboard, switches)
pd.DataFrame(reports.device_rows(switches, data)).to_excel("switches.xlsx", index=False)
Contribute
Create a branch to add your feature/fix then submit a merge request to main for review. Be sure to follow the correct format in your commit message to trigger the pipeline to submit a new release. Example commit below.
feat: Added the ability to update switch configurations.
fix: Fixes some bug.
BREAKING CHANGE: Updated function API.
Run the tests before you submit:
pip install -e ".[test]"
pytest
Metadata
Release files for readyview 1.19.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| readyview-1.19.0.tar.gz | 73.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| readyview-1.19.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 121.5 kB
Release files / readyview-1.19.0.tar.gz
| Download URL | readyview-1.19.0.tar.gz |
|---|---|
| Size | 73.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
50c1736b9343cbdeb8f90143b4e748c2c88aad9d3943ab7be2f390026e67f2f5
|
|
BLAKE2b-256 checksum How to use checksums |
13f6c949eaf811e8fc7c623174ff3b078cff1d9d621bde541678efb8d95fbde4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Hatch/1.18.1 {"ci":true,"cpu":"x86_64","distro":{"id":"trixie","libc":{"lib":"glibc","version":"2.41"},"name":"Debian GNU/Linux","version":"13"},"implementation":{"name":"CPython","version":"3.11.17"},"installer":{"name":"hatch","version":"1.18.1"},"openssl_version":"OpenSSL 3.5.7 9 Jun 2026","python":"3.11.17","system":{"name":"Linux","release":"5.15.154+"}} HTTPX2/2.13.1
|
Release files / readyview-1.19.0-py3-none-any.whl
| Download URL | readyview-1.19.0-py3-none-any.whl |
|---|---|
| Size | 47.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2827908c0caeab4303331704be6c696e80cddb8fb70934b2fd619b5059c6183e
|
|
BLAKE2b-256 checksum How to use checksums |
c184287be8d5eae4108585ce02e18ec4cb339cc0f986d11d2a30def67f84ac6b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Hatch/1.18.1 {"ci":true,"cpu":"x86_64","distro":{"id":"trixie","libc":{"lib":"glibc","version":"2.41"},"name":"Debian GNU/Linux","version":"13"},"implementation":{"name":"CPython","version":"3.11.17"},"installer":{"name":"hatch","version":"1.18.1"},"openssl_version":"OpenSSL 3.5.7 9 Jun 2026","python":"3.11.17","system":{"name":"Linux","release":"5.15.154+"}} HTTPX2/2.13.1
|