Metadata-Version: 2.4
Name: pyvyos
Version: 0.4.1
Summary: Python SDK for interacting with the VyOS HTTPS API
Project-URL: Homepage, https://github.com/vyos-contrib/pyvyos
Project-URL: Issues, https://github.com/vyos-contrib/pyvyos/issues
Project-URL: Changelog, https://github.com/vyos-contrib/pyvyos/blob/main/CHANGELOG.md
Author-email: Roberto Berto <463349+robertoberto@users.noreply.github.com>
License: MIT License
        
        Copyright (c) 2023 GravScale, Roberto Bertó
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: api,firewall,networking,router,sdk,vyos
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Networking
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: requests<3.0,>=2.34.2
Provides-Extra: dev
Requires-Dist: pytest-cov<8.0,>=7.1.0; extra == 'dev'
Requires-Dist: pytest-env<1.3,>=0.6.2; extra == 'dev'
Requires-Dist: pytest<10.0,>=8.0; extra == 'dev'
Requires-Dist: python-dotenv<2.0,>=1.2.2; extra == 'dev'
Description-Content-Type: text/markdown

# pyvyos

[![PyPI version](https://img.shields.io/pypi/v/pyvyos.svg)](https://pypi.org/project/pyvyos/)
[![Python versions](https://img.shields.io/pypi/pyversions/pyvyos.svg)](https://pypi.org/project/pyvyos/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![PR Validation](https://github.com/vyos-contrib/pyvyos/actions/workflows/python-pr-validation.yml/badge.svg)](https://github.com/vyos-contrib/pyvyos/actions/workflows/python-pr-validation.yml)

Python SDK for the [VyOS](https://vyos.io/) HTTPS API.

`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.

## Installation

```bash
pip install pyvyos
```

Requires **Python 3.11 or newer**. Tested on 3.11, 3.12, and 3.13.

## Quick start

Enable the HTTPS API on the VyOS device and create an API key:

```text
set service https api rest
set service https api keys id my-key key 'your-secret-key'
commit
```

> The `set service https api rest` line is required. Without it the
> HTTPS service only exposes `/info` and every other endpoint returns
> `404`. See the VyOS docs for the [HTTP API service](https://docs.vyos.io/en/latest/configuration/service/https.html).

Then, from Python:

```python
import os
from pyvyos import VyDevice

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() in ("1", "true", "yes"),
)

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)
```

## Environment variables

A `.env.example` is shipped with the project. The recognised variables are:

| 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.          |

`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`.

## API overview

All methods return an `ApiResponse` dataclass with four fields:

```python
@dataclass
class ApiResponse:
    status: int                       # HTTP status code
    request: dict                     # the request payload (API key redacted)
    result: dict | list | str | None  # parsed `data` field from the response
    error: str | bool                 # error message, or False on success
```

`result` varies per endpoint: configuration retrieval returns a `dict` or
`list`, operational commands like `show`/`generate` often return a `str`,
and some endpoints return `None`.

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)
```

### Configuration

```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(op_path=[
    {"op": "set",    "path": ["interfaces", "dummy", "dum2", "address", "203.0.113.1/24"]},
    {"op": "delete", "path": ["interfaces", "dummy", "dum1"]},
])
```

### Retrieval

```python
device.retrieve_show_config(path=["system"])
device.retrieve_return_values(path=["interfaces", "dummy", "dum1", "address"])
```

### Operational

```python
device.show(path=["system", "image"])
device.generate(path=["ssh", "client-key", "/tmp/key"])
device.reset(path=["conntrack-sync", "internal-cache"])
```

### 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")
```

### System control

```python
device.reboot()      # equivalent to device.reboot(path=["now"])
device.poweroff()    # equivalent to device.poweroff(path=["now"])
```

### Image management

```python
device.image_add(url="https://downloads.vyos.io/.../vyos-1.4-image.iso")
device.image_delete(name="1.4-rolling-...")
```

## Public API stability

The supported public API of pyvyos is:

```python
from pyvyos import VyDevice, ApiResponse
```

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
```

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` | Final shim behaviour decided before release, based on observed usage and maintenance cost. |

## Examples

- [`examples/basic.py`](examples/basic.py) — read-only end-to-end usage
  example. Safe to run against any reachable device.
- [`examples/integration_smoke.py`](examples/integration_smoke.py) —
  exercises mutating operations (`configure_set/delete`, `generate`,
  `config_file_save/load`). Intended for a disposable lab; guarded by the
  `PYVYOS_ALLOW_MUTATING_EXAMPLE=1` environment variable.
- [`examples/vagrant/`](examples/vagrant/) — Vagrant-based VyOS lab for
  local development and integration testing.

## Logging

`pyvyos` uses the standard `logging` module under the `pyvyos` namespace.
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)
```

Log records contain structural fields only (`command`, `op`, `status`,
`elapsed_ms`) and never include the request payload or the API key.

The request payload returned via `ApiResponse.request` is sanitised — the
`key` field is replaced with `***REDACTED***` before the response is
handed back to the caller.

## VyOS compatibility

Tested live against:

- VyOS rolling `2026.05.18-0045` (current rolling at release time)

The library only depends on the HTTPS API surface, so older 1.4 / 1.5
builds that expose the same endpoints should work without changes,
but they are not exercised on every release. The live harness under
[`tests/pve/`](tests/pve/) makes it easy to re-run the suite against
any VyOS build you care about.

Required device-side configuration for the live API:

```text
set service https api rest
set service https api keys id <id> key '<secret>'
```

## Development

The project uses [uv](https://docs.astral.sh/uv/) for environment
management:

```bash
uv sync --extra dev
uv run pytest
```

Optional code-style hooks:

```bash
pip install pre-commit
pre-commit install
```

### Live VyOS testing

The regular test suite is mock-based and does not need a VyOS device.

For maintainers, this repository ships an opt-in harness under
[`tests/pve/`](tests/pve/) that creates a disposable VyOS VM on a
local Proxmox host and runs `tests/e2e` against the real HTTPS API.
It is not part of the default GitHub Actions workflow. See the
harness README for setup.

## 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).
