diff options
| author | Roberto Bertó <463349+robertoberto@users.noreply.github.com> | 2026-05-19 02:39:01 +0000 |
|---|---|---|
| committer | Roberto Bertó <463349+robertoberto@users.noreply.github.com> | 2026-05-19 02:39:01 +0000 |
| commit | bf4e309a698592cdb815580f97db97b268fd6668 (patch) | |
| tree | e8adb51a364d3fa617133f85603ab03d536ce849 /README.md | |
| parent | ea8c349f6dce955696850198b8544d0203b467fb (diff) | |
| download | pyvyos-bf4e309a698592cdb815580f97db97b268fd6668.tar.gz pyvyos-bf4e309a698592cdb815580f97db97b268fd6668.zip | |
docs: prepare v0.4.0 release
Rewrite the README around the supported public API, add a public API
stability policy, document the deprecation timeline, and refresh the
CHANGELOG with the full 0.4.0 scope. Add a short CONTRIBUTING guide.
Apply minor pending fixes to LICENSE and .env.example. Fix a couple of
verify=False antipatterns in the docs/ pages.
README:
- Badges (PyPI version, Python versions, license, CI).
- Quick start that actually runs (no missing import, no global
disable_warnings, correct VYDEVICE_VERIFY_SSL parse).
- Environment variable table with defaults.
- ApiResponse contract documented as a dataclass.
- Compact API overview (configure / retrieve / show / generate / reset /
config-file / system / image).
- Public API stability section with the 0.4 -> 0.5 -> 0.6 -> 1.0
deprecation timeline.
- Logging section: NullHandler default, pyvyos logger, redacted key.
- VyOS compatibility note (1.4 LTS, 1.5 rolling).
- Development with uv; optional pre-commit.
CHANGELOG:
- Consolidated 0.4.0 entry covering both the architecture refactor and
this cleanup, since 0.4.0 was tagged in git but never published.
- Explicit Added / Changed / Removed / Fixed / Compatibility / Notes
sections.
- 0.3.0 entry annotated as 'tagged but never released to PyPI'.
CONTRIBUTING.md:
- Scope statement (thin HTTPS API wrapper).
- Pull request rules; explicit 'do not change HTTP payload in passing'.
- Development setup with uv.
- Public API stability summary.
Fixes from the previous review-fixes branch:
- LICENSE copyright now reads 'GravScale, Roberto Berto'.
- .env.example default flipped to VYDEVICE_VERIFY_SSL=true with
field descriptions.
- docs/getting-started.md: VERIFY_SSL default to true; urllib3
disable_warnings now passes the specific InsecureRequestWarning.
- docs/index.md: quick example uses verify=True; removed RTD link
(RTD config was removed in this release because the build never
worked).
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 272 |
1 files changed, 174 insertions, 98 deletions
@@ -1,149 +1,225 @@ -# pyvyos Documentation +# pyvyos -pyvyos is a Python library for interacting with VyOS devices via their API. This documentation provides a guide on how to use pyvyos to manage your VyOS devices programmatically. +[](https://pypi.org/project/pyvyos/) +[](https://pypi.org/project/pyvyos/) +[](LICENSE) +[](https://github.com/vyos-contrib/pyvyos/actions/workflows/python-pr-validation.yml) -You can find the complete pyvyos documentation on [Read the Docs](https://pyvyos.readthedocs.io/en/latest/). +Python SDK for the [VyOS](https://vyos.io/) HTTPS API. -## Installation +`pyvyos` is a small, focused library that wraps the VyOS HTTPS API in an +idiomatic Python interface. It is intended for automation scripts, internal +tooling, and integrations with configuration management systems. -You can install pyvyos using pip https://pypi.org/project/pyvyos/: +## Installation ```bash pip install pyvyos ``` -## Getting Started +Requires **Python 3.13 or newer**. -### Importing and Disabling Warnings for verify=False -Before using pyvyos, it's a good practice to disable urllib3 warnings and import the required modules, IF you use verify=False: - -``` -import urllib3 -urllib3.disable_warnings() -``` +## Quick start -### Using API Response Class -pyvyos uses a custom ApiResponse data class to handle API responses: +Enable the HTTPS API on the VyOS device and create an API key: -``` -@dataclass -class ApiResponse: - status: int - request: dict - result: dict - error: str +```text +set service https api keys id my-key key 'your-secret-key' +commit ``` -### Initializing a VyDevice Object +Then, from Python: +```python +import os +from pyvyos import VyDevice -#### Configuring Your Environment for VyDevice -1. Rename the file .env.example to .env. -1. Open the .env file in a text editor. -1. Replace the placeholder values with your VyOS device credentials: - - **VYDEVICE_HOSTNAME**: Your device's hostname or IP address. - - **VYDEVICE_APIKEY**: Your API key for authentication. - - **VYDEVICE_PORT**: The port number for the API. Default 443 - - **VYDEVICE_PROTOCOL**: The protocol (e.g., http or https). Default https - - **VYDEVICE_VERIFY_SSL**: Set to True or False for SSL verification. +device = VyDevice( + hostname=os.environ["VYDEVICE_HOSTNAME"], + apikey=os.environ["VYDEVICE_APIKEY"], + port=int(os.environ.get("VYDEVICE_PORT", "443")), + protocol=os.environ.get("VYDEVICE_PROTOCOL", "https"), + verify=os.environ.get("VYDEVICE_VERIFY_SSL", "true").lower() == "true", +) +response = device.show(path=["system", "image"]) +if response.error: + print(f"Error {response.status}: {response.error}") +else: + print(response.result) +``` +If you use self-signed certificates, set `verify=False` **only in lab +environments** and silence the urllib3 warning explicitly: + +```python +import urllib3 +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) ``` -# Retrieve VyOS device connection details from environment variables and configure VyDevice -from dotenv import load_dotenv -load_dotenv() -hostname = os.getenv('VYDEVICE_HOSTNAME') -apikey = os.getenv('VYDEVICE_APIKEY') -port = os.getenv('VYDEVICE_PORT') -protocol = os.getenv('VYDEVICE_PROTOCOL') -verify_ssl = os.getenv('VYDEVICE_VERIFY_SSL') +## Environment variables -# Convert the verify_ssl value to a boolean -verify = verify_ssl.lower() == "true" if verify_ssl else True +A `.env.example` is shipped with the project. The recognised variables are: -device = VyDevice(hostname=hostname, apikey=apikey, port=port, protocol=protocol, verify=verify) -``` +| Variable | Default | Purpose | +| ---------------------- | ------- | -------------------------------------------------- | +| `VYDEVICE_HOSTNAME` | — | Hostname or IP address of the VyOS device. | +| `VYDEVICE_APIKEY` | — | API key configured on the device. | +| `VYDEVICE_PORT` | `443` | HTTPS port of the VyOS API. | +| `VYDEVICE_PROTOCOL` | `https` | `https` (recommended) or `http`. | +| `VYDEVICE_VERIFY_SSL` | `true` | Verify the TLS certificate of the device. | -## Using pyvyos +`pyvyos` does not read these variables on its own — your application is +responsible for loading them (for example with `python-dotenv`) and passing +the values to `VyDevice`. -### configure, then set -The configure_set method sets a VyOS configuration: +## API overview -``` -# Set a VyOS configuration -response = device.configure_set(path=["interfaces", "ethernet", "eth0", "address", "192.168.1.1/24"]) +All methods return an `ApiResponse` dataclass with four fields: -# Check for errors and print the result -if not response.error: - print(response.result) -``` -### configure, then show a single OBJECT value -``` -# Retrieve VyOS return values for a specific interface -response = device.retrieve_return_values(path=["interfaces", "dummy", "dum1", "address"]) -print(response.result) +```python +@dataclass +class ApiResponse: + status: int # HTTP status code + request: dict # the request payload (API key removed) + result: dict | list # parsed `data` field from the response + error: str | bool # error message, or False on success ``` -### configure, then show OBJECT -The retrieve_show_config method retrieves the VyOS configuration: +The recommended usage pattern is: +```python +response = device.retrieve_show_config(path=["interfaces"]) +if response.error: + raise RuntimeError(response.error) +do_something_with(response.result) ``` -# Retrieve the VyOS configuration -response = device.retrieve_show_config(path=[]) -# Check for errors and print the result -if not response.error: - print(response.result) -``` +### Configuration -### configure, then delete OBJECT -``` -# Delete a VyOS interface configuration -response = device.configure_delete(path=["interfaces", "dummy", "dum1"]) +```python +device.configure_set(path=["interfaces", "ethernet", "eth0", "address", "192.0.2.1/24"]) +device.configure_delete(path=["interfaces", "dummy", "dum1"]) +device.configure_multiple_op(path=[ + {"op": "set", "path": ["interfaces", "dummy", "dum2", "address", "203.0.113.1/24"]}, + {"op": "delete", "path": ["interfaces", "dummy", "dum1"]}, +]) ``` -### configure, then save -``` -# Save VyOS configuration without specifying a file (default location) -response = device.config_file_save() -``` +### Retrieval -### configure, then save FILE +```python +device.retrieve_show_config(path=["system"]) +device.retrieve_return_values(path=["interfaces", "dummy", "dum1", "address"]) ``` -# Save VyOS configuration to a specific file -response = device.config_file_save(file="/config/test300.config") + +### Operational + +```python +device.show(path=["system", "image"]) +device.generate(path=["ssh", "client-key", "/tmp/key"]) +device.reset(path=["conntrack-sync", "internal-cache"]) ``` -## show OBJECT +### Configuration files + +```python +device.config_file_save() # default location +device.config_file_save(file="/config/backup.config") +device.config_file_load(file="/config/backup.config") ``` -# Show VyOS system image information -response = device.show(path=["system", "image"]) -print(response.result) + +### System control + +```python +device.reboot() # equivalent to device.reboot(path=["now"]) +device.poweroff() # equivalent to device.poweroff(path=["now"]) ``` -### generate OBJECT +### Image management + +```python +device.image_add(url="https://downloads.vyos.io/.../vyos-1.4-image.iso") +device.image_delete(name="1.4-rolling-...") ``` -# Generate an SSH key with a random string in the name -randstring = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(20)) -keyrand = f'/tmp/key_{randstring}' -response = device.generate(path=["ssh", "client-key", keyrand]) + +## Public API stability + +The supported public API of pyvyos is: + +```python +from pyvyos import VyDevice, ApiResponse ``` -### reset OBJECT -The reset method allows you to run a reset command: +These compatibility imports continue to work without warnings and will be +kept while the migration cost remains trivial: +```python +from pyvyos.device import VyDevice +from pyvyos.rest import RestClient, ApiResponse ``` -# Execute the reset command -response = device.reset(path=["conntrack-sync", "internal-cache"]) -# Check for errors and print the result -if not response.error: - print(response.result) +Anything under `pyvyos.core.*` is internal implementation detail and may +change between minor releases. + +The deprecation timeline is: + +| Release | Status | +| ------- | ----------------------------------------------------------------- | +| `0.4.x` | Compatibility shims work without warnings. | +| `0.5.x` | Internal solidity work; shims still silent. | +| `0.6.x` | Compatibility shims emit a `DeprecationWarning`. | +| `1.0.0` | Shims are removed or kept, depending on observed usage. | + +## Logging + +`pyvyos` uses the standard `logging` module under the `pyvyos` namespace and +attaches a `NullHandler` so a default install does not print anything. + +To see request/response activity, configure the logger in your application: + +```python +import logging +logging.basicConfig(level=logging.INFO) +logging.getLogger("pyvyos").setLevel(logging.DEBUG) ``` -### configure, then load FILE +Request payloads are sanitised before logging — the `key` field is replaced +with `***REDACTED***`. + +## VyOS compatibility + +Tested against: + +- VyOS 1.4 LTS (stable) +- VyOS 1.5 rolling + +The library only depends on the HTTPS API surface, so versions that expose +the same endpoints should work without changes. + +## Development + +The project uses [uv](https://docs.astral.sh/uv/) for environment +management: + +```bash +uv sync --extra dev +uv run pytest ``` -# Load VyOS configuration from a specific file -response = device.config_file_load(file="/config/test300.config") + +Optional code-style hooks: + +```bash +pip install pre-commit +pre-commit install ``` + +## Contributing + +Bug reports and pull requests are welcome. Please open an issue first to +discuss anything beyond a small fix, and keep changes focused — payload and +public-API changes go through a separate review cycle. + +## License + +MIT — see [LICENSE](LICENSE). |
