- Added a repository URL section in `pyproject.toml` to link to the GitHub repository. - Updated installation instructions in `README.md` to reflect the change from Gitea to GitHub as the source for package installation, removing references to the private Gitea Package Registry.
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 from the source repository. It is not published to PyPI yet.
Requirements: Python 3.10+
From GitHub Source
Install directly from the repository:
pip install git+https://github.com/sttarsky/oxipy.git
Install a specific tag or branch:
pip install git+https://github.com/sttarsky/oxipy.git@v0.1.0
pip install git+https://github.com/sttarsky/oxipy.git@dev
For local development:
git clone https://github.com/sttarsky/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.