IluaAir 2a03240414 Update setuptools version and modify license information in pyproject.toml
- Updated the required setuptools version from 61 to 77 to ensure compatibility with the latest features and improvements.
- Changed the license format in `pyproject.toml` to specify "Apache-2.0" directly and added a reference to the license file for clarity.
2026-05-28 15:55:20 +03:00
2026-02-14 01:07:26 +03:00

oxipy

oxipy is a Python client for the Oxidized API. It fetches device configurations from Oxidized and parses them into structured Pydantic models using bundled TTP templates.

Oxidized remains responsible for collecting and storing configuration backups. oxipy focuses on consuming those backups from Python code and exposing common configuration sections such as system data, interfaces, and VLANs.

Contents

Installation

The package is distributed through a private Gitea Package Registry and from the source repository. It is not published to PyPI.

Requirements: Python 3.10+

From Gitea Package Registry

Install the package by pointing pip to the private registry:

pip install oxipy \
  --index-url https://gitea.imbastark.ru/api/packages/Netbox/pypi/simple/

You can also configure the registry permanently in pip.conf or pip.ini:

# ~/.config/pip/pip.conf  (Linux/macOS)
# %APPDATA%\pip\pip.ini   (Windows)

[global]
extra-index-url = https://gitea.imbastark.ru/api/packages/Netbox/pypi/simple/

After that, install normally:

pip install oxipy

If the registry requires authentication, pass a token in the index URL:

pip install oxipy \
  --index-url https://__token__:<your_token>@gitea.imbastark.ru/api/packages/Netbox/pypi/simple/

From Gitea Source

Install directly from the repository:

pip install git+https://gitea.imbastark.ru/Netbox/oxipy.git

Install a specific tag or branch:

pip install git+https://gitea.imbastark.ru/Netbox/oxipy.git@v0.1.0
pip install git+https://gitea.imbastark.ru/Netbox/oxipy.git@dev

For local development:

git clone https://gitea.imbastark.ru/Netbox/oxipy
cd oxipy
pip install -e .

Quick Start

from oxi import OxiAPI

api = OxiAPI(url="https://oxi.example.com", verify=False)

node = api.node("Router_HOME")

print(node.ip)
print(node.model)
print(node.full_name)

print(node.config.system.model)
print(node.config.interfaces.dump_json())
print(node.config.vlans.dump_json())

Example output:

192.168.1.1
keenetic
router/HQ
Sprinter (KN-3710)
[
  {"interface": "Bridge1", "ip_address": "192.168.1.1", "mask": 24, "description": "Guest network"},
  {"interface": "Bridge0", "ip_address": "172.16.1.1", "mask": 24, "description": "Home network"}
]
[
  {"vlan_id": 1, "description": "Home VLAN"},
  {"vlan_id": 2, "description": "Ethernet uplink"},
  {"vlan_id": 3, "description": "Home network"}
]

API Reference

OxiAPI

OxiAPI is the entry point. It manages the HTTP session and provides access to Oxidized nodes.

OxiAPI(
    url: str,
    username: str | None = None,
    password: str | None = None,
    verify: bool = True,
)
Parameter Type Description
url str Base URL of the Oxidized API, for example https://oxi.example.com.
username `str None`
password `str None`
verify bool Whether to verify TLS certificates. Defaults to True.

Example:

# Without authentication
api = OxiAPI(url="https://oxi.example.com")

# With HTTP basic authentication
api = OxiAPI(
    url="https://oxi.example.com",
    username="admin",
    password="secret",
)

# As a context manager. The HTTP session is closed automatically.
with OxiAPI(url="https://oxi.example.com") as api:
    node = api.node("HQ")
    print(node.ip)

api.node(name)

Returns a NodeView for the requested Oxidized node.

node = api.node("HQ")

NodeView

NodeView represents one network device. It contains metadata returned by Oxidized and lazy access to the fetched configuration.

Property Type Description
ip str Node IP address.
full_name str Full node name in Oxidized.
group str Oxidized group the node belongs to.
model str Device model key used to select a parser.
config NodeConfig Device configuration, fetched and parsed on first access.

Example:

node = api.node("HQ")

print(node.ip)
print(node.group)
print(node.model)

NodeConfig

NodeConfig fetches and parses a device configuration. The parser is selected from the device registry by the node model value returned by Oxidized.

Configuration sections are exposed through properties that return ModelView objects.

Property Returns Description
system ModelView[System] System information.
interfaces ModelView[list[Interfaces]] Parsed interface list.
vlans ModelView[list[Vlans]] Parsed VLAN list, if the template provides VLAN data.
text str Raw configuration text fetched from Oxidized.

Example:

cfg = node.config

print(cfg.system.model)
print(cfg.system.serial_number)
print(cfg.system.version)

for iface in cfg.interfaces:
    print(iface.name, iface.ip_address, iface.mask)

first_iface = cfg.interfaces[0]
print(first_iface.name)
print(len(cfg.interfaces))

print(cfg.interfaces.dump_json())
print(cfg.vlans.dump_json())
print(cfg.system.dump_json())

print(cfg.text)

NodeConfig also provides dump() and dump_json() methods for the whole parsed device object.

ModelView

ModelView wraps either a single Pydantic model or a list of Pydantic models. It provides serialization, iteration for list sections, and transparent access to model attributes.

Method / operation Applies to Description
.dump() single model and list Returns a Python dict or list using aliases.
.dump_json() single model and list Returns a JSON string using aliases.
.<attr> single model and list Proxies attribute access to the wrapped model.
iter(view) list only Iterates over wrapped models.
len(view) list only Returns the number of wrapped models.
view[i] list only Returns an item or slice.

__iter__, __len__, and __getitem__ are available only for list-backed sections such as interfaces and vlans. Calling them on system raises TypeError.

Examples:

system = node.config.system
print(system.dump_json())
print(system.model)
print(system.serial_number)

interfaces = node.config.interfaces

for iface in interfaces:
    print(iface.name, iface.ip_address)

print(len(interfaces))
print(interfaces[0])
print(interfaces[:3])
print(interfaces.dump())

Supported Devices

Registry keys are compared with the Oxidized node model value case-insensitively.

Device Registry keys
Keenetic ndms, keenetic, keeneticos
MikroTik routeros, ros, mikrotik
Qtech qtech
Huawei huawei, vrp
Eltex eltex
H3C h3c
Quasar qos, quasar

You can add support for another device family by creating a new device model and TTP template. See Extending Device Models.

Additional Documentation

Description
Oxidized api wrapper for python
Readme 283 KiB