From 7164b24d66ff57a16649d70db9cdcca3ddf4a39b Mon Sep 17 00:00:00 2001 From: Fedor Zhukov Date: Fri, 22 May 2026 09:53:04 +0200 Subject: [PATCH] chore: drop support for netbox v24 Since I am preparing breaking changes I decided to go ahead and drop support of v24. It was never actively used nor maintained. Hence API coverage is luckluster at best: % grep -cr ^class src/annetbox/v*/models.py src/annetbox/v24/models.py:8 src/annetbox/v37/models.py:33 src/annetbox/v41/models.py:34 src/annetbox/v42/models.py:36 Also netbox-data does not provide DB snapshots for v2 so keeping feature parity while maintaining compability is non-trivial. So I decided its better to burn it than let it rot and pretend that v2 is suppported at all. --- AGENTS.md | 4 +- src/annetbox/v24/__init__.py | 0 src/annetbox/v24/client_async.py | 57 ---------------------- src/annetbox/v24/client_sync.py | 57 ---------------------- src/annetbox/v24/models.py | 84 -------------------------------- 5 files changed, 2 insertions(+), 200 deletions(-) delete mode 100644 src/annetbox/v24/__init__.py delete mode 100644 src/annetbox/v24/client_async.py delete mode 100644 src/annetbox/v24/client_sync.py delete mode 100644 src/annetbox/v24/models.py diff --git a/AGENTS.md b/AGENTS.md index ab2f8ea..dce6835 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,7 +4,7 @@ This file provides guidance to AI coding agents when working with code in this r ## Project Overview -Annetbox is a Netbox API client library for Python used by annet and related projects. It implements a subset of Netbox API methods with support for multiple Netbox versions (v24, v37, v41, v42). The library provides both synchronous and asynchronous clients. +Annetbox is a Netbox API client library for Python used by annet and related projects. It implements a subset of Netbox API methods with support for multiple Netbox versions (v37, v41, v42). The library provides both synchronous and asynchronous clients. ## Development Commands @@ -92,7 +92,7 @@ python -m build ## Code Architecture ### Version-based Structure -The codebase is organized by Netbox API versions, each in its own module (`v24/`, `v37/`, `v41/`, `v42/`). Each version module contains: +The codebase is organized by Netbox API versions, each in its own module (`v37/`, `v41/`, `v42/`). Each version module contains: - `models.py` - Dataclass models for API responses/requests - `client_async.py` - Async client implementation - `client_sync.py` - Sync client (auto-generated from async) diff --git a/src/annetbox/v24/__init__.py b/src/annetbox/v24/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/annetbox/v24/client_async.py b/src/annetbox/v24/client_async.py deleted file mode 100644 index 3b49369..0000000 --- a/src/annetbox/v24/client_async.py +++ /dev/null @@ -1,57 +0,0 @@ -from datetime import datetime - -import dateutil.parser -from adaptix import Retort, loader -from dataclass_rest import get - -from annetbox.base.client_async import BaseNetboxClient, collect -from annetbox.base.models import PagingResponse -from .models import Device, Interface, IpAddress - - -class NetboxV24(BaseNetboxClient): - def _init_response_body_factory(self) -> Retort: - return Retort(recipe=[loader(datetime, dateutil.parser.parse)]) - - # dcim - @get("dcim/interfaces/") - async def dcim_interfaces( - self, - device_id: list[int] | None = None, - limit: int = 20, - offset: int = 0, - ) -> PagingResponse[Interface]: - pass - - dcim_all_interfaces = collect(dcim_interfaces, field="device_id") - - @get("dcim/devices/") - async def dcim_devices( - self, - name: list[str] | None = None, - tag: str | None = None, - limit: int = 20, - offset: int = 0, - ) -> PagingResponse[Device]: - pass - - dcim_all_devices = collect(dcim_devices) - - @get("dcim/devices/{device_id}/") - async def dcim_device( - self, - device_id: int, - ) -> Device: - pass - - # ipam - @get("ipam/ip-addresses/") - async def ipam_ip_addresses( - self, - interface_id: list[int] | None = None, - limit: int = 20, - offset: int = 0, - ) -> PagingResponse[IpAddress]: - pass - - ipam_all_ip_addresses = collect(ipam_ip_addresses, field="interface_id") diff --git a/src/annetbox/v24/client_sync.py b/src/annetbox/v24/client_sync.py deleted file mode 100644 index 9a4ff72..0000000 --- a/src/annetbox/v24/client_sync.py +++ /dev/null @@ -1,57 +0,0 @@ -from datetime import datetime - -import dateutil.parser -from adaptix import Retort, loader -from dataclass_rest import get - -from annetbox.base.client_sync import BaseNetboxClient, collect -from annetbox.base.models import PagingResponse -from .models import Device, Interface, IpAddress - - -class NetboxV24(BaseNetboxClient): - def _init_response_body_factory(self) -> Retort: - return Retort(recipe=[loader(datetime, dateutil.parser.parse)]) - - # dcim - @get("dcim/interfaces/") - def dcim_interfaces( - self, - device_id: list[int] | None = None, - limit: int = 20, - offset: int = 0, - ) -> PagingResponse[Interface]: - pass - - dcim_all_interfaces = collect(dcim_interfaces, field="device_id") - - @get("dcim/devices/") - def dcim_devices( - self, - name: list[str] | None = None, - tag: str | None = None, - limit: int = 20, - offset: int = 0, - ) -> PagingResponse[Device]: - pass - - dcim_all_devices = collect(dcim_devices) - - @get("dcim/devices/{device_id}") - def dcim_device( - self, - device_id: int, - ) -> Device: - pass - - # ipam - @get("ipam/ip-addresses/") - def ipam_ip_addresses( - self, - interface_id: list[int] | None = None, - limit: int = 20, - offset: int = 0, - ) -> PagingResponse[IpAddress]: - pass - - ipam_all_ip_addresses = collect(ipam_ip_addresses, field="interface_id") diff --git a/src/annetbox/v24/models.py b/src/annetbox/v24/models.py deleted file mode 100644 index 344991b..0000000 --- a/src/annetbox/v24/models.py +++ /dev/null @@ -1,84 +0,0 @@ -from dataclasses import dataclass -from datetime import datetime -from typing import Any - - -@dataclass -class Entity: - id: int - name: str - - -@dataclass -class Label: - value: int - label: str - - -@dataclass -class DeviceType: - id: int - manufacturer: Entity - model: str - - -@dataclass -class DeviceIp: - id: int - address: str - family: int - - -@dataclass -class Device(Entity): - url: str - display_name: str - device_type: DeviceType - device_role: Entity - tenant: Entity | None - platform: Entity | None - serial: str - asset_tag: str | None - site: Entity - rack: Entity | None - position: float | None - face: Label | None - status: Label - primary_ip: DeviceIp | None - primary_ip4: DeviceIp | None - primary_ip6: DeviceIp | None - tags: list[str] - custom_fields: dict[str, Any] - created: datetime - last_updated: datetime - - -@dataclass -class Interface(Entity): - device: Entity - enabled: bool - - -@dataclass -class Vrf(Entity): - rd: str - - -@dataclass -class IpAddress: - id: int - family: int - address: str - vrf: Vrf | None - tenant: Any # ??? - status: Label - description: str | None - custom_fields: dict[str, Any] - tags: list[str] - created: datetime - last_updated: datetime - - interface: Entity - - nat_inside: Any # ??? - nat_outside: Any # ???