Skip to content
This repository was archived by the owner on Jun 27, 2025. It is now read-only.

Commit b265733

Browse files
authored
Add render_config, update docs, v0.1.6 (#11)
1 parent ca5a9aa commit b265733

File tree

12 files changed

+206
-7
lines changed

12 files changed

+206
-7
lines changed

docs/index.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,109 @@
66
[![License](https://img.shields.io/github/license/netbox-community/netbox-python)](https://img.shields.io/github/license/netbox-community/netbox-python)
77

88
Python NetBox API Client
9+
10+
## Installation
11+
12+
To install run `pip install netbox-python`.
13+
14+
Alternatively, you can clone the repo and run `python setup.py install`.
15+
16+
## Usage
17+
18+
To begin, import the NetBox client and instantiate it:
19+
20+
```
21+
from netbox_python import NetBoxClient, Result
22+
nb = NetBoxClient(
23+
base_url="http://127.0.0.1:8000/", token="1dc6fa5bfcef8390dd83a261c36ed8f1551b2d6b"
24+
)
25+
```
26+
The first argument NetBoxClient takes is the NetBox URL. The 'token' argument is from NetBox, see the [Authentication documentation](https://docs.netbox.dev/en/stable/integrations/rest-api/#authentication) in the NetBox docs for more about creating and using API Tokens.
27+
28+
Now using the client you can make calls to the api.
29+
30+
### Basic CRUD APIs
31+
32+
Each of these objects has the standard CRUD endpoints as follows:
33+
34+
```
35+
# 1. List (paginated)
36+
ret = nb.dcim.sites.list(limit=3)
37+
38+
# 2. Filtered List
39+
ret = nb.dcim.sites.list(region_id="43")
40+
41+
# 3. All
42+
ret = nb.dcim.sites.all()
43+
44+
# 4. Get
45+
ret = nb.dcim.sites.get(24)
46+
47+
# 5. Create
48+
ret = nb.dcim.sites.create(name="foo3", slug="foo3")
49+
50+
# 6. Update
51+
ret = nb.dcim.sites.update(26, name="foo2-new", slug="foo2-new-slug")
52+
53+
# 7. Delete
54+
ret = nb.dcim.sites.delete(37)
55+
```
56+
57+
### Bulk APIs
58+
59+
In addition, bulk operations are available on the API's as well:
60+
```
61+
# 8. Bulk Create
62+
data = [
63+
{"name": "foo4", "slug": "foo4"},
64+
{"name": "foo5", "slug": "foo5"},
65+
{"name": "foo6", "slug": "foo6"},
66+
]
67+
ret = nb.dcim.sites.create(data)
68+
69+
# 8. Bulk Update
70+
data = [
71+
{"id": 28, "name": "foo4-new", "slug": "foo4-new"},
72+
{"id": 29, "name": "foo5-new", "slug": "foo5-new"},
73+
]
74+
ret = nb.dcim.sites.update(data)
75+
76+
# 10. Bulk Delete
77+
data = [{"id": 25}, {"id": 27}]
78+
ret = nb.dcim.sites.delete(data)
79+
```
80+
### Special APIs
81+
82+
In addition to the standard API calls above, devices also have a special API for rendering config context:
83+
```
84+
ret = nb.dcim.devices.render_config(107)
85+
```
86+
87+
### Endpoints
88+
89+
The methods on the api's correspond to the NetBox REST API - the best reference to the objects that can be called is by using the [browsable API](https://demo.netbox.dev/api/) on the netbox instance. The root objects that can be called are:
90+
91+
- circuits
92+
- core
93+
- dcim
94+
- extras
95+
- ipam
96+
- plugins
97+
- status
98+
- tenancy
99+
- users
100+
- virtualization
101+
- wireless
102+
103+
circuits would have 'circuit_terminations', 'circuit_types', etc... off of it. Each of the endpoints has 'list', 'get', 'create', 'update' and 'delete' functions.
104+
105+
106+
## Return Object
107+
108+
The return object from the API calls is a dictionary with two values (response and data). **data** is the actual data returned from the call and response contains detailed information on the call, including the HTTP status code returned. Netbox-python is a wrapper around the python [requests](https://github.com/psf/requests) library. Detailed information on the response object can be found in python requests library [documentation](https://requests.readthedocs.io/en/latest/). After making an API call you can check the status code and get the returned data as follows:
109+
110+
```
111+
ret = nb.dcim.sites.all()
112+
print(f"status code: {ret.response.status_code}")
113+
print(ret.data)
114+
```

netbox_python/api/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
from netbox_python.api.asn_range import asn_range
12
from netbox_python.api.circuits import circuits
23
from netbox_python.api.core import core
34
from netbox_python.api.dcim import dcim
45
from netbox_python.api.extras import extras
6+
from netbox_python.api.ip_range import ip_range
57
from netbox_python.api.ipam import ipam
68
from netbox_python.api.plugins import plugins
9+
from netbox_python.api.prefix import prefix
710
from netbox_python.api.tenancy import tenancy
811
from netbox_python.api.users import users
912
from netbox_python.api.virtualization import virtualization
13+
from netbox_python.api.vlan_group import vlan_group
1014
from netbox_python.api.wireless import wireless

netbox_python/api/asn_range.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from netbox_python.baseapi import AvailableAPIResource
2+
3+
4+
class asn_range:
5+
def __init__(self, client):
6+
self.available_asns = self._available_asns(client)
7+
super().__init__()
8+
9+
class _available_asns(AvailableAPIResource):
10+
path = "ipam/asn-ranges/{id}/available-asns"

netbox_python/api/dcim.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from netbox_python.baseapi import APIResource
1+
from netbox_python.baseapi import APIResource, CreateableAPIResource
2+
from netbox_python.rest import Result
23

34

45
class dcim:
@@ -83,6 +84,9 @@ class _device_types(APIResource):
8384
class _devices(APIResource):
8485
path = "dcim/devices/"
8586

87+
def render_config(self, id: str | int, *args, **kwargs) -> Result:
88+
return self._create(f"{self.path}{id}/render-config/", *args, **kwargs)
89+
8690
class _front_port_templates(APIResource):
8791
path = "dcim/front-port-templates/"
8892

netbox_python/api/extras.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from netbox_python.baseapi import APIResource
2+
from netbox_python.rest import Result
23

34

45
class extras:
@@ -26,6 +27,9 @@ class _config_contexts(APIResource):
2627
class _config_templates(APIResource):
2728
path = "extras/config-templates/"
2829

30+
def render(self, id: str | int, *args, **kwargs) -> Result:
31+
return self._create(f"{self.path}{id}/render/", *args, **kwargs)
32+
2933
class _content_types(APIResource):
3034
path = "extras/content-types/"
3135

netbox_python/api/ip_range.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from netbox_python.baseapi import AvailableAPIResource
2+
3+
4+
class ip_range:
5+
def __init__(self, client):
6+
self.available_ips = self._available_ips(client)
7+
super().__init__()
8+
9+
class _available_ips(AvailableAPIResource):
10+
path = "ipam/ip-ranges/{id}/available-ips"

netbox_python/api/ipam.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
1+
from netbox_python.api.asn_range import asn_range
2+
from netbox_python.api.ip_range import ip_range
3+
from netbox_python.api.prefix import prefix
4+
from netbox_python.api.vlan_group import vlan_group
15
from netbox_python.baseapi import APIResource
26

37

48
class ipam:
59
def __init__(self, client):
610
self.aggregates = self._aggregates(client)
711
self.asns = self._asns(client)
12+
self.asn_ranges = self._asn_ranges(client)
13+
self.asn_range = asn_range(client)
814
self.fhrp_group_assignments = self._fhrp_group_assignments(client)
915
self.fhrp_groups = self._fhrp_groups(client)
1016
self.ip_addresses = self._ip_addresses(client)
1117
self.ip_ranges = self._ip_ranges(client)
18+
self.ip_range = ip_range(client)
1219
self.l2vpn_terminations = self._l2vpn_terminations(client)
1320
self.l2vpns = self._l2vpns(client)
1421
self.prefixes = self._prefixes(client)
@@ -28,6 +35,9 @@ class _aggregates(APIResource):
2835
class _asns(APIResource):
2936
path = "ipam/asns/"
3037

38+
class _asn_ranges(APIResource):
39+
path = "ipam/asn-ranges/"
40+
3141
class _fhrp_group_assignments(APIResource):
3242
path = "ipam/fhrp-group-assignments/"
3343

netbox_python/api/prefix.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from netbox_python.baseapi import AvailableAPIResource
2+
3+
4+
class prefix:
5+
def __init__(self, client):
6+
self.available_ips = self._available_ips(client)
7+
self.available_prefixes = self._available_prefixes(client)
8+
super().__init__()
9+
10+
class _available_ips(AvailableAPIResource):
11+
path = "ipam/prefixes/{id}/available-ips"
12+
13+
class _available_prefixes(AvailableAPIResource):
14+
path = "ipam/prefixes/{id}/available-prefixes"

netbox_python/api/vlan_group.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from netbox_python.baseapi import AvailableAPIResource
2+
3+
4+
class vlan_group:
5+
def __init__(self, client):
6+
self.available_vlans = self._available_vlans(client)
7+
super().__init__()
8+
9+
class _available_vlans(AvailableAPIResource):
10+
path = "ipam/vlan-groups/{id}/available-vlans"

netbox_python/baseapi.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ def __init__(self, client):
1010

1111

1212
class CreateableAPIResource:
13+
def _create(self, path, *args, **kwargs) -> Result:
14+
return self.client.post(path, json=args[0] if args else kwargs)
15+
1316
def create(self, *args, **kwargs) -> Result:
14-
return self.client.post(self.path, json=args[0] if args else kwargs)
17+
return self._create(self.path, *args, **kwargs)
1518

1619

1720
class DeletableAPIResource:
@@ -33,12 +36,15 @@ def paginate(self, result: Result) -> Result:
3336
yield result
3437
next_token = result.pagination["next"]
3538

39+
def _list(self, path, **kwargs) -> Result:
40+
return self.client.get(path, params=kwargs)
41+
3642
def list(self, **kwargs) -> Result:
37-
return self.client.get(self.path, params=kwargs)
43+
return self._list(self.path, **kwargs)
3844

39-
def all(self, **kwargs):
45+
def _all(self, path, **kwargs):
4046
result = None
41-
for page in self.paginate(self.client.get(self.path, params=kwargs)):
47+
for page in self.paginate(self._list(path, **kwargs)):
4248
if not result:
4349
result = page
4450
else:
@@ -48,6 +54,9 @@ def all(self, **kwargs):
4854
result.pagination["previous"] = None
4955
return result
5056

57+
def all(self, **kwargs):
58+
return self._all(self.path, **kwargs)
59+
5160

5261
class RetrievableAPIResource:
5362
def get(self, id: str | int) -> Result:
@@ -86,3 +95,21 @@ class ROAPIResource(
8695
UpdateableAPIResource,
8796
):
8897
pass
98+
99+
100+
class AvailableAPIResource(
101+
baseapi,
102+
CreateableAPIResource,
103+
ListableAPIResource,
104+
):
105+
def create(self, id: str | int, *args, **kwargs) -> Result:
106+
path = self.path.format(id=id)
107+
return self._create(path, *args, **kwargs)
108+
109+
def list(self, id: str | int, **kwargs) -> Result:
110+
path = self.path.format(id=id)
111+
return self._list(path, **kwargs)
112+
113+
def all(self, id: str | int, **kwargs):
114+
path = self.path.format(id=id)
115+
return self._all(path, **kwargs)

0 commit comments

Comments
 (0)