axlib
Axlib is an educational Python package for Network Operations staff building automation scripts. It combines pipeline-friendly text filters with reusable credential helpers that can resolve operator credentials without embedding passwords in source code.
Highlights
import axlib as ax; ax.getkeys()remains the simple network-credential API.$USERselects the operator record when no service is supplied.NETUSER,NETPASS, andNETENABLEoverride stored fields.- A configured shared service remains the fallback when an operator is not yet enlisted.
- Redis can optionally cache plaintext values with TLS, authentication, TTL, and timeouts.
- SQLite stores service payloads with AES-256-GCM.
- The native encrypted text store also uses AES-256-GCM and no longer depends on
keyringorkeyrings.cryptfile. - Both durable stores use parallel Python CRUD methods and parallel administration CLIs.
- Both durable stores support in-place AES-256 key rotation that re-encrypts every record.
StoreAdminis one Python administration API for either store; both CLIs and the optional TUI are thin layers over it.- An optional full-screen credential manager (TUI) gives non-developers an "easy button" for their
ax.getkeys()records, locally or over SSH. - Every record may carry a short, non-secret note (owner, purpose, expiry) that the TUI and
listshow and lookups ignore. axlib netenv-set/axlib netenv-clearloadNETUSER,NETPASS, andNETENABLEinto an operator's shell at SSH login, and clear them again.axlib radiuschecks a username and password against a RADIUS server, as a network device would, and reports Accept, Reject, or Challenge.axlib parseparses show-command output with TextFSM (the ntc-templates collection plus your own.textfsmfiles), andaxlib parse diffcompares collections taken before and after a change record by record, so neighbors listed in another order or hold times that ticked down are not reported as changes.
Install
This project uses uv. Add axlib to your project:
uv add axlib
Add the optional full-screen credential manager as well:
uv add 'axlib[tui]'
Add show-command parsing (axlib parse):
uv add 'axlib[textfsm]'
To install axlib for every operator on a shared Linux host (a shared Python in /opt/shared/python, axlib in /opt/shared/axlib, and a ready netops credential store), unpack a release tarball and run its installer:
tar xzf axlib-<version>.tar.gz
sudo ./axlib-<version>/install.sh
The installer records its options in /etc/axlib/install.env, so the axlib command finds /etc/axlib/axlib.toml without --config, and upgrades need no options. Administrators add libraries such as netmiko for every script with sudo axuv add netmiko; axuv runs uv on the shared environment with the installer's settings. See docs/INSTALL.md for options, upgrades, rollback, and backups.
Runtime dependencies are limited to cryptography and redis. Redis is imported only when caching is enabled. The optional tui extra adds textual and rich, and the optional textfsm extra adds textfsm and ntc-templates.
Existing automation API
import axlib as ax
netuser, netpass, netenable = ax.getkeys()
Lookup precedence for each missing field is environment/caller, Redis, SQLite when enabled, then the encrypted text file when enabled.
Standard credential administration
axlib credential-file init --generate-key
axlib credential-file add --service "$USER" --set netuser="$USER" --prompt netpass --prompt netenable
axlib credential-file list
axlib credential-db init --generate-key
axlib credential-db add --service "$USER" --set netuser="$USER" --prompt netpass --prompt netenable
axlib credential-db list
axlib credential-file rotate-key --generate-key --yes
axlib credential-db rotate-key --generate-key --yes
Both commands provide init, add, update, delete, list, and rotate-key. Both support --set FIELD=VALUE, --from-env FIELD=ENV_VAR, secure --prompt FIELD, --profile network|infoblox, update --remove FIELD, and JSON listing.
Credential manager (TUI)
Operators who run scripts built on ax.getkeys() but do not write Python can manage their records in a full-screen terminal UI:
uv add 'axlib[tui]'
axlib credential-tui --config /etc/axlib/axlib.toml
It lists each service's field names with notes explaining how ax.getkeys() will use them, and it adds, edits, and deletes records, initializes stores, and rotates keys. Credential values are never displayed. See docs/CREDENTIAL_TUI.md.
Session credentials at login
Operators can have their network login exported into every SSH session:
eval "$(axlib netenv-set)" # export NETUSER, NETPASS, NETENABLE from $USER's record
eval "$(axlib netenv-clear)" # unset them
examples/netenv/netenv.sh wraps both in the netenv-set and netenv-clear shell functions and loads credentials when an interactive bash or zsh shell starts. The uv scripts scripts/netenv-set and scripts/netenv-clear run the same commands from a checkout, from any directory. Read the warnings in docs/NETENV.md before enabling this: exported passwords are visible to every program the shell starts.
Python administration API
The same operations are available to Python code, with the same validation, profile rules, and Redis cache invalidation as the CLIs and the TUI:
from axlib.credentials import StoreAdmin, StoreKind, load_settings
admin = StoreAdmin(load_settings("/etc/axlib/axlib.toml"), StoreKind.SQLITE)
admin.initialize(generate_key=True)
admin.add("first.last", {"netuser": "first.last", "netpass": password})
admin.update("first.last", remove=["netenable"])
print(admin.status().state) # "ready"
python -m axlib.credentials.admin --json prints a health check of every configured store, and python -m axlib.credentials.profiles lists the fields each record profile expects.
RADIUS login check
When a device login fails, ask the RADIUS server directly whether it accepts the account:
axlib radius 192.0.2.10 -u "$NETUSER" --password-env NETPASS --secret-file /etc/axlib/radius.secret
from axlib.radius import authenticate
result = authenticate("192.0.2.10", "alice", password, secret) # port=1812 by default
print(result.reply.code_name, result.accepted)
The exit status is 0 for Access-Accept, 1 for Reject or Challenge, 2 for errors, and 3 when no reply arrives. --json prints the full result. The module uses only the standard library and is checked against the RFC 2865 test vectors. See docs/RADIUS.md.
Show-command parsing
Collect show commands before and after a maintenance window, then see only what changed:
axlib parse -p cisco_ios -r captures/before/ -o before.json
axlib parse diff -p cisco_ios -r before.json captures/after/
sw1: show cdp neighbors
- local_interface=GigabitEthernet1/0/5 neighbor_name=ap-lobby-01
~ local_interface=GigabitEthernet1/0/48 neighbor_name=core-rtr-01.example.net
neighbor_interface: GigabitEthernet0/0/1 -> GigabitEthernet0/0/2
Captures can be session logs with prompts (sw1#show cdp neighbors), script output with bare commands, whole directory trees (-r), or output piped from ssh (--command). Abbreviated commands such as sh cdp nei are recognized. Records are sorted by what identifies them, interface names are spelled one way (Gig 1/0/48, Gi1/0/48 → GigabitEthernet1/0/48), and fields that change on every run are dropped. To add a template, put cisco_ios_show_ip_pim_neighbor.textfsm (platform, then the command) in a template directory: --template-dir, AXLIB_TEXTFSM_TEMPLATES, or /etc/axlib/textfsm on a shared server. Template directories are searched before ntc-templates.
from axlib.parse import parse_output
records = parse_output(
conn.send_command("show cdp neighbors"), "show cdp neighbors", "cisco_ios"
)
See docs/PARSING.md.
Shared server example
[credentials]
shared_service = "network-shared"
[credential_file]
enabled = true
file = "/var/lib/axlib/credentials.axc"
key_file = "/etc/axlib/credential-file.key"
file_mode = "0660"
key_file_mode = "0640"
group = "netops"
[sqlite]
enabled = true
database = "/var/lib/axlib/credentials.db"
key_file = "/etc/axlib/sqlite-aes256.key"
database_mode = "0660"
key_file_mode = "0640"
group = "netops"
When both durable stores are enabled, SQLite is preferred before the encrypted text file. The key files may live outside the data directory, and relative paths in TOML are resolved relative to the configuration file.
Storage-version policy
Axlib intentionally performs no credential-store migrations. The text store accepts only its current format version and AES-256-GCM cipher. SQLite accepts only its current axlib schema version. Unsupported versions fail clearly so operators can deliberately recreate/reprovision a store rather than have startup mutate it.
Text filters
The axlib.tf modules can be imported or placed in shell pipelines:
python -m axlib tf include site.conf \
| python -m axlib tf comments \
| python -m axlib tf variables -v hostname=edge-01 \
| python -m axlib tf whitespace \
> site.rendered.conf
See docs/TEXT_FILTERS.md for filter semantics.
Documentation
docs/INSTALL.md— shared-host installation withinstall.sh: layout, options, upgrades, rollback, backups.docs/CREDENTIALS.md— lookup precedence, configuration, CLI, administration API, and permissions.docs/CREDENTIAL_TUI.md— operator guide for the optional full-screen credential manager.docs/NETENV.md— loading credentials into SSH sessions withnetenv-set/netenv-clear: setup, warnings, and troubleshooting.docs/RADIUS.md— checking a login against a RADIUS server withaxlib radius: options, exit status, Python API, how it works, and troubleshooting.docs/PARSING.md— parsing show commands withaxlib parseand comparing collections withaxlib parse diff: capture formats, output, adding your own TextFSM templates, Python API, and troubleshooting.docs/CREDENTIAL_FILE.md— full encrypted text-store API with examples for every method.docs/SQLITE_CREDENTIALS.md— full SQLite API with examples for every method.docs/TEXT_FILTERS.md— pipeline and Python text-processing examples.docs/DEVELOPMENT.md— development and validation guidance.
The source intentionally includes detailed module/function docstrings and comments explaining both what Python constructs do and why they are useful in network automation.
Metadata
Release files for axlib 1.0.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| axlib-1.0.6.tar.gz | 298.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| axlib-1.0.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 504.0 kB
Release files / axlib-1.0.6.tar.gz
| Download URL | axlib-1.0.6.tar.gz |
|---|---|
| Size | 298.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
87965657c140964097be60745a46055426393889041b0b62502ef9f8275fecfe
|
|
BLAKE2b-256 checksum How to use checksums |
7ba1ed32ba0b67bc9a844462f802d0f8eae80a48f73e57340185e5397f837fe0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.15.0
|
Release files / axlib-1.0.6-py3-none-any.whl
| Download URL | axlib-1.0.6-py3-none-any.whl |
|---|---|
| Size | 205.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b51a6a7b98a634b65b50b33156cc8d4232554ce232df8f53db71576d733e2560
|
|
BLAKE2b-256 checksum How to use checksums |
cedb39fe5dca80f5aab1b429550993119c1a514d8618d33379d2f15375a754ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.15.0
|
Security for axlib 1.0.6
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.