Skip to main content

Async NetBox API Client

Project description

Code style: black PyPI License: APACHE-2.0 Docs Codecov

anac

Python Async NetBox API Client, based on httpx and pydantic

Documentation

https://timeforplanb123.github.io/anac

Features

  • Minimalistic interface
  • Async only
  • Python interpreter autocompletion
  • Supports NetBox 2.x, 3.x
  • Flexibility. All the objects are coroutines or coroutine iterators
  • Simple integration with parsers (TextFSM, TTP)

Quick Start

Install

Please, at first, check the dependencies in pyproject.toml and create new virtual environment if necessary and then:

with pip:

pip install anac 

with git:

git clone https://github.com/timeforplanb123/anac.git
cd anac 
pip install .
# or
poetry install

Simple Examples

Api Instantiating

from anac import api

a = api(
    "https://demo.netbox.dev",
    token="cf1dc7b04de5f27cfc93aba9e3f537d2ad6fdf8c",
)
# get openapi spec and create attributes/endpoints   
await a.openapi()

get some device and patch it

asciicast

In [1]: some_device = await a.dcim_devices(get={"name": "dmi01-rochster-sw01"})

In [2]: some_device.name
Out[2]: 'dmi01-rochster-sw01'

In [3]: some_device.device_type
Out[3]:
{'id': 7,
 'url': 'https://demo.netbox.dev/api/dcim/device-types/7/',
 'display': 'C9200-48P',
 'manufacturer': {'id': 3,
  'url': 'https://demo.netbox.dev/api/dcim/manufacturers/3/',
  'display': 'Cisco',
  'name': 'Cisco',
  'slug': 'cisco'},
 'model': 'C9200-48P',
 'slug': 'c9200-48p'}

In [4]: some_device.status
Out[4]: {'value': 'active', 'label': 'Active'}

In [5]: some_device = await some_device(patch={"status": "failed"})

In [6]: some_device.status
Out[6]: {'value': 'failed', 'label': 'Failed'}

get some 2 devices and put + patch them

In [7]: some_devices = await a.dcim_devices(
    ...:     get=[{"name": "dmi01-rochster-sw01"}, {"name": "dmi01-rochester-rtr01"}]
    ...: )

# EndpointAsIterator is a coroutine iterator with 2 coroutines
In [8]: some_devices
Out[8]: EndpointAsIterator(api=Api, url='https://demo.netbox.dev/api', endpoint='/dcim/devices/')

In [9]: import asyncio

# run 2 coroutines in the event loop
In [10]: some_devices = await asyncio.gather(*some_devices)

# EndpointId is a NetBox '/dcim/devices/' object and coroutine
In [11]: some_devices
Out[11]: 
[EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/21/', endpoint='/dcim/devices/'),
 EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/8/', endpoint='/dcim/devices/')]

In [12]: patch_some_devices = [coro(patch={"status": "failed"}) for coro in some_devices]

# run 2 coroutines in the event loop
In [13]: patch_some_devices = await asyncio.gather(*patch_some_devices)

# EndpointId is a coroutine, again
In [14]: patch_some_devices
Out[14]: 
[EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/21/', endpoint='/dcim/devices/{id}/'),
 EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/8/', endpoint='/dcim/devices/{id}/')]

In [15]: patch_some_devices[0].name
Out[15]: 'dmi01-rochster-sw01'

In [16]: patch_some_devices[0].status
Out[16]: {'value': 'failed', 'label': 'Failed'}

In [17]: patch_some_devices[1].name
Out[17]: 'dmi01-rochester-rtr01'

In [18]: patch_some_devices[1].status
Out[18]: {'value': 'failed', 'label': 'Failed'}

get all devices

In [19]: all_devices = await a.dcim_devices(get={})
# or
In [20]: all_devices = await a.dcim_devices()

# EndpointIdIterator is an coroutine iterator with EndpointId objects
In [21]: all_devices
Out[21]: EndpointIdIterator(api=Api, url='https://demo.netbox.dev/api', endpoint='/dcim/devices/')

In [22]: len(all_devices)
Out[22]: 50

In [23]: all_devices[49]
Out[23]: EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/95/', endpoint='/dcim/devices/')

In [24]: all_devices[49].name
Out[24]: 'ncsu118-distswitch1'

# by default, 'limit' parameter = 50, but you can run 'get' request with custom 'limit'
In [25]: all_devices = await a.dcim_devices(get={"limit": 100})

In [26]: len(all_devices)
Out[26]: 75

In [27]: all_devices[74]
Out[27]: EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/106/', endpoint='/dcim/devices/')

In [28]: all_devices[74].id
Out[28]: 106

get all devices and post 2 new devices

In [29]: all_test = await a.dcim_devices(
    ...:     get={},
    ...:     post=[
    ...:         {
    ...:             "name": "test1",
    ...:             "device_role": 1,
    ...:             "site": 1,
    ...:             "device_type": 1,
    ...:             "status": "planned",
    ...:         },
    ...:         {
    ...:             "name": "test2",
    ...:             "device_role": 1,
    ...:             "site": 1,
    ...:             "device_type": 1,
    ...:             "status": "planned",
    ...:         },
    ...:     ],
    ...: )

# run 3 coroutines in the event loop
In [30]: all_test = await asyncio.gather(*all_test)

# EndpointIdIterator is an coroutine iterator with EndpointId objects
# EndpointId is a NetBox '/dcim/devices/' object and coroutine
In [31]: all_test
Out[31]: 
[EndpointIdIterator(api=Api, url='https://demo.netbox.dev/api', endpoint='/dcim/devices/'),
 EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/110/', endpoint='/dcim/devices/'),
 EndpointId(api=Api, url='https://demo.netbox.dev/api/dcim/devices/111/', endpoint='/dcim/devices/')]

In [32]: all_test[0][49].name
Out[32]: 'ncsu118-distswitch1'

In [33]: all_test[1].name
Out[34]: 'test1'

In [35]: all_test[2].name
Out[35]: 'test2'

# httpx.Response is available with .response attribute
In [36]: all_test[1].response.json()
Out[36]:
{'id': 110,
 'url': 'https://demo.netbox.dev/api/dcim/devices/110/',
 'display': 'test1',
 'name': 'test1',
 'device_type': {'id': 1,
  'url': 'https://demo.netbox.dev/api/dcim/device-types/1/',
  'display': 'MX480',
  'manufacturer': {'id': 7,
  ...
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

anac-0.1.2.tar.gz (15.8 kB view details)

Uploaded Source

Built Distribution

anac-0.1.2-py3-none-any.whl (14.7 kB view details)

Uploaded Python 3

File details

Details for the file anac-0.1.2.tar.gz.

File metadata

  • Download URL: anac-0.1.2.tar.gz
  • Upload date:
  • Size: 15.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.13 CPython/3.9.13 Linux/5.13.0-1029-azure

File hashes

Hashes for anac-0.1.2.tar.gz
Algorithm Hash digest
SHA256 1c570617569880036fc2a58a8cb1ab92c6858c2d71462cddb0534d97be5ea392
MD5 13abf21d284dae4cf45b9b8829486f46
BLAKE2b-256 a6c3fc706edf556c63719f1d510a90c42f8d9725278ecec797ac10c2e8e8a9aa

See more details on using hashes here.

File details

Details for the file anac-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: anac-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 14.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.13 CPython/3.9.13 Linux/5.13.0-1029-azure

File hashes

Hashes for anac-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 3808b12809bdc343e297a8f0913b393caffd6763886d1bb7c2ac2e4e2cf50fdf
MD5 8d6d1847a2186a306aa11d5a5b04f0d2
BLAKE2b-256 cc38881648b898ff635ac354a300ef8646b2fbed5bc98d9221ac03e97fb7b9b0

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page