nbforager 0.8.0__tar.gz → 0.8.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. {nbforager-0.8.0 → nbforager-0.8.2}/PKG-INFO +2 -2
  2. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/base_c.py +43 -48
  3. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/connector.py +4 -0
  4. nbforager-0.8.2/nbforager/constants.py +283 -0
  5. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/helpers.py +2 -275
  6. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/nb_api.py +13 -15
  7. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/types_.py +3 -3
  8. {nbforager-0.8.0 → nbforager-0.8.2}/pyproject.toml +2 -2
  9. {nbforager-0.8.0 → nbforager-0.8.2}/LICENSE.txt +0 -0
  10. {nbforager-0.8.0 → nbforager-0.8.2}/README.rst +0 -0
  11. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/__init__.py +0 -0
  12. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/__init__.py +0 -0
  13. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/base_ac.py +0 -0
  14. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/circuits.py +0 -0
  15. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/core.py +0 -0
  16. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/dcim.py +0 -0
  17. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/extended_get.py +0 -0
  18. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/extras.py +0 -0
  19. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/ip_addresses.py +0 -0
  20. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/ipam.py +0 -0
  21. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/plugins_ca.py +0 -0
  22. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/status.py +0 -0
  23. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/tenancy.py +0 -0
  24. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/users.py +0 -0
  25. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/virtualization.py +0 -0
  26. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/api/wireless.py +0 -0
  27. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/exceptions.py +0 -0
  28. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/foragers/__init__.py +0 -0
  29. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/foragers/base_fa.py +0 -0
  30. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/foragers/circuits.py +0 -0
  31. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/foragers/core.py +0 -0
  32. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/foragers/dcim.py +0 -0
  33. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/foragers/extras.py +0 -0
  34. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/foragers/forager.py +0 -0
  35. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/foragers/ipam.py +0 -0
  36. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/foragers/ipv4.py +0 -0
  37. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/foragers/joiner.py +0 -0
  38. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/foragers/tenancy.py +0 -0
  39. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/foragers/users.py +0 -0
  40. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/foragers/virtualization.py +0 -0
  41. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/foragers/wireless.py +0 -0
  42. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/log.py +0 -0
  43. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/messages.py +0 -0
  44. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/nb_cache.py +0 -0
  45. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/nb_forager.py +0 -0
  46. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/nb_tree.py +0 -0
  47. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/parser/__init__.py +0 -0
  48. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/parser/nb_custom.py +0 -0
  49. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/parser/nb_parser.py +0 -0
  50. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/parser/nb_value.py +0 -0
  51. {nbforager-0.8.0 → nbforager-0.8.2}/nbforager/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: nbforager
3
- Version: 0.8.0
3
+ Version: 0.8.2
4
4
  Summary: Python package designed to assist in working with the Netbox REST API. The filter parameters are identical to those in the Web UI filter form. It replaces brief data with full information, and Netbox objects are represented as a recursive multidimensional dictionary.
5
5
  License: Apache-2.0
6
6
  Keywords: netbox
@@ -23,7 +23,7 @@ Requires-Dist: requests (>=2,<3)
23
23
  Requires-Dist: tabulate (>=0.9,<0.10)
24
24
  Requires-Dist: vhelpers (>=0.3)
25
25
  Project-URL: Bug Tracker, https://github.com/vladimirs-git/nbforager/issues
26
- Project-URL: Download URL, https://github.com/vladimirs-git/nbforager/archive/refs/tags/0.8.0.tar.gz
26
+ Project-URL: Download URL, https://github.com/vladimirs-git/nbforager/archive/refs/tags/0.8.2.tar.gz
27
27
  Project-URL: homepage, https://github.com/vladimirs-git/nbforager
28
28
  Project-URL: repository, https://github.com/vladimirs-git/nbforager
29
29
  Description-Content-Type: text/x-rst
@@ -13,13 +13,13 @@ from operator import itemgetter
13
13
  from queue import Queue
14
14
  from threading import Thread
15
15
  from typing import Callable
16
- from urllib.parse import urlencode, ParseResult
16
+ from urllib.parse import ParseResult
17
17
 
18
18
  import netports
19
19
  import requests
20
20
  from requests import Session, Response
21
21
  from requests.exceptions import ReadTimeout, ConnectionError as RequestsConnectionError
22
- from vhelpers import vdict, vlist, vparam
22
+ from vhelpers import vlist, vparam
23
23
 
24
24
  from nbforager import helpers as h
25
25
  from nbforager.api import extended_get
@@ -293,7 +293,7 @@ class BaseC:
293
293
  params_d_["brief"] = 1
294
294
  params_d_["limit"] = 1
295
295
  params_l: LParam = vparam.from_dict(params_d_)
296
- url = f"{self.url_base}{path}?{urlencode(params_l)}"
296
+ url = f"{self.url_base}{path}?{urllib.parse.urlencode(params_l)}"
297
297
  response: Response = self._retry_requests(url)
298
298
 
299
299
  count = 0
@@ -316,62 +316,43 @@ class BaseC:
316
316
 
317
317
  :return: Netbox objects. Update self _results.
318
318
  """
319
- offset = 0
320
- if offsets := params_d.get("offset"):
321
- offset = int(offsets[0])
319
+ params_d = params_d.copy()
320
+ if "limit" not in params_d:
321
+ params_d["limit"] = [self.limit]
322
+ if "offset" not in params_d:
323
+ params_d["offset"] = [0]
322
324
 
323
- max_limit: int = self._set_limit(params_d)
324
325
  params_l: LParam = vparam.from_dict(params_d)
326
+ url = f"{self.url_base}{path}?{urllib.parse.urlencode(params_l)}"
325
327
 
326
328
  results: LDAny = []
327
329
  while True:
328
- params_i = [*params_l, ("offset", offset)]
329
- url = f"{self.url_base}{path}?{urlencode(params_i)}"
330
330
  response: Response = self._retry_requests(url)
331
- if response.ok:
332
- html: str = response.content.decode("utf-8")
333
- data: DAny = json.loads(html)
334
- results_: LDAny = list(data["results"])
335
- results.extend(results_)
336
- else:
337
- results_ = []
338
-
339
- # stop requests if limit reached
340
- if self.limit != len(results_):
331
+ if not response.ok:
341
332
  break
342
- if max_limit and max_limit <= len(results):
333
+
334
+ html: str = response.content.decode("utf-8")
335
+ data: DAny = json.loads(html)
336
+ results_: LDAny = list(data["results"])
337
+ results.extend(results_)
338
+
339
+ # retrieve next offset from Response
340
+ if url_next := str(data.get("next") or ""):
341
+ url = url_next
342
+ else:
343
343
  break
344
344
 
345
- # next iteration
345
+ # Sleep before the next iteration to reduce server load
346
346
  if self.interval:
347
347
  time.sleep(self.interval)
348
- offset += self.limit
349
348
 
350
349
  return results
351
350
 
352
- def _set_limit(self, params_d: DList) -> int:
353
- """Update limit valur in params_d based on limit and max_limit
354
-
355
- :return: Max limit value, update params_d["limit"] value
356
- """
357
- limit = 0
358
- if limit_ := list(vdict.pop(data=params_d, key="limit") or []):
359
- limit = int(limit_[0])
360
- if not limit:
361
- limit = self.limit
362
- max_limit = 0
363
- if max_limit_ := list(vdict.pop(data=params_d, key="max_limit") or []):
364
- max_limit = int(max_limit_[0])
365
- if max_limit and max_limit < limit:
366
- limit = max_limit
367
- params_d["limit"] = [limit]
368
- return max_limit
369
-
370
351
  def _query_data_thread(self, path: str, params_d: DAny) -> None:
371
- """Retrieve data from the Netbox.
352
+ """Retrieve data from the Netbox and appends results to the internal results list.
372
353
 
373
- If the number of items in the result exceeds the limit, iterate through the offset
374
- in a loop mode.
354
+ If the params_d does not have `offset` and the received Response contains "next" URL,
355
+ the method will recurse to fetch the next set of data.
375
356
 
376
357
  :param path: Section of the URL that points to the model.
377
358
  :param params_d: Parameters to request from the Netbox.
@@ -379,12 +360,26 @@ class BaseC:
379
360
  :return: Netbox objects. Update self _results.
380
361
  """
381
362
  params_l: LParam = vparam.from_dict(params_d)
382
- url = f"{self.url_base}{path}?{urlencode(params_l)}"
363
+ url = f"{self.url_base}{path}?{urllib.parse.urlencode(params_l)}"
364
+
383
365
  response: Response = self._retry_requests(url)
384
- if response.ok:
385
- html: str = response.content.decode("utf-8")
386
- data: DAny = json.loads(html)
387
- results_: LDAny = list(data["results"])
366
+ if not response.ok:
367
+ return
368
+
369
+ html: str = response.content.decode("utf-8")
370
+ data: DAny = json.loads(html)
371
+ results_: LDAny = list(data["results"])
372
+ self._results.extend(results_)
373
+
374
+ # threading mode manage offset in top level method
375
+ if "offset" in params_d:
376
+ return
377
+
378
+ # retrieve next offset from Response
379
+ if url_next := str(data.get("next") or ""):
380
+ url_o: ParseResult = urllib.parse.urlparse(url_next)
381
+ params_d_: DAny = urllib.parse.parse_qs(url_o.query)
382
+ results_ = self._query_loop(path=path, params_d=params_d_)
388
383
  self._results.extend(results_)
389
384
 
390
385
  def _query_pages_count(self, params_ld: LDList) -> LDAny:
@@ -5,6 +5,7 @@
5
5
  from __future__ import annotations
6
6
 
7
7
  import json
8
+ from typing import Generator
8
9
 
9
10
  from requests import Response
10
11
  from vhelpers import vdict
@@ -169,3 +170,6 @@ class Connector(BaseC):
169
170
  html: str = response.content.decode("utf-8")
170
171
  data: DAny = dict(json.loads(html))
171
172
  return data
173
+
174
+
175
+ GConnector = Generator[Connector, None, None]
@@ -0,0 +1,283 @@
1
+ """Constants for apps and models."""
2
+
3
+ from nbforager.types_ import DLStr
4
+
5
+ APPS = (
6
+ "circuits",
7
+ "core",
8
+ "dcim",
9
+ "extras",
10
+ "ipam",
11
+ "plugins",
12
+ "tenancy",
13
+ "users",
14
+ "virtualization",
15
+ "wireless",
16
+ )
17
+ """Application names for NetBox v3.5."""
18
+
19
+ DEPENDENT_MODELS: DLStr = {
20
+ "circuits/circuit-terminations": [
21
+ "circuits/circuits",
22
+ "circuits/provider-networks",
23
+ "dcim/cable-terminations",
24
+ "dcim/sites",
25
+ "extras/tags",
26
+ ],
27
+ "circuits/circuit-types": ["extras/tags"],
28
+ "circuits/circuits": [
29
+ "circuits/circuit-types",
30
+ "circuits/provider-accounts",
31
+ "circuits/providers",
32
+ "extras/tags",
33
+ "tenancy/tenants",
34
+ ],
35
+ "circuits/provider-accounts": ["circuits/providers", "extras/tags"],
36
+ "circuits/provider-networks": ["circuits/providers", "extras/tags"],
37
+ "circuits/providers": ["extras/tags", "ipam/asns"],
38
+ "core/data-files": ["core/data-sources"],
39
+ "core/data-sources": ["extras/tags"],
40
+ "core/jobs": ["extras/content-types"],
41
+ "dcim/cable-terminations": [
42
+ "dcim/cables",
43
+ "dcim/devices",
44
+ "dcim/locations",
45
+ "dcim/racks",
46
+ "dcim/sites",
47
+ ],
48
+ "dcim/cables": ["extras/tags", "tenancy/tenants"],
49
+ "dcim/console-port-templates": ["dcim/device-types", "dcim/module-types"],
50
+ "dcim/console-ports": [
51
+ "dcim/cable-terminations",
52
+ "dcim/devices",
53
+ "dcim/modules",
54
+ "extras/tags",
55
+ ],
56
+ "dcim/console-server-port-templates": ["dcim/device-types", "dcim/module-types"],
57
+ "dcim/console-server-ports": [
58
+ "dcim/cable-terminations",
59
+ "dcim/devices",
60
+ "dcim/modules",
61
+ "extras/tags",
62
+ ],
63
+ "dcim/device-bay-templates": ["dcim/device-types"],
64
+ "dcim/device-bays": ["dcim/devices", "extras/tags"],
65
+ "dcim/device-roles": ["extras/config-templates", "extras/tags"],
66
+ "dcim/device-types": ["dcim/manufacturers", "extras/tags"],
67
+ "dcim/devices": [
68
+ "dcim/device-roles",
69
+ "dcim/device-types",
70
+ "dcim/locations",
71
+ "dcim/platforms",
72
+ "dcim/racks",
73
+ "dcim/sites",
74
+ "dcim/virtual-chassis",
75
+ "extras/config-templates",
76
+ "extras/tags",
77
+ "tenancy/tenants",
78
+ "virtualization/clusters",
79
+ ],
80
+ "dcim/front-port-templates": [
81
+ "dcim/device-types",
82
+ "dcim/module-types",
83
+ "dcim/rear-port-templates",
84
+ ],
85
+ "dcim/front-ports": [
86
+ "dcim/cable-terminations",
87
+ "dcim/devices",
88
+ "dcim/modules",
89
+ "dcim/rear-ports",
90
+ "extras/tags",
91
+ ],
92
+ "dcim/interface-templates": ["dcim/device-types", "dcim/module-types"],
93
+ "dcim/interfaces": [
94
+ "dcim/cable-terminations",
95
+ "dcim/devices",
96
+ "dcim/modules",
97
+ "dcim/virtual-device-contexts",
98
+ "extras/tags",
99
+ "ipam/ip-addresses",
100
+ "ipam/l2vpn-terminations",
101
+ "ipam/vlans",
102
+ "ipam/vrfs",
103
+ "virtualization/interfaces",
104
+ "wireless/wireless-lans",
105
+ ],
106
+ "dcim/inventory-item-roles": ["extras/tags"],
107
+ "dcim/inventory-item-templates": [
108
+ "dcim/device-types",
109
+ "dcim/inventory-item-roles",
110
+ "dcim/manufacturers",
111
+ ],
112
+ "dcim/inventory-items": [
113
+ "dcim/devices",
114
+ "dcim/inventory-item-roles",
115
+ "dcim/manufacturers",
116
+ "extras/tags",
117
+ ],
118
+ "dcim/locations": ["dcim/sites", "extras/tags", "ipam/vlan-groups", "tenancy/tenants"],
119
+ "dcim/manufacturers": ["extras/tags"],
120
+ "dcim/module-bay-templates": ["dcim/device-types"],
121
+ "dcim/module-bays": ["dcim/devices", "extras/tags"],
122
+ "dcim/module-types": ["dcim/manufacturers", "extras/tags"],
123
+ "dcim/modules": ["dcim/devices", "dcim/module-bays", "dcim/module-types", "extras/tags"],
124
+ "dcim/platforms": ["dcim/manufacturers", "extras/config-templates", "extras/tags"],
125
+ "dcim/power-feeds": [
126
+ "dcim/cable-terminations",
127
+ "dcim/power-panels",
128
+ "dcim/racks",
129
+ "extras/tags",
130
+ ],
131
+ "dcim/power-outlet-templates": [
132
+ "dcim/device-types",
133
+ "dcim/module-types",
134
+ "dcim/power-port-templates",
135
+ ],
136
+ "dcim/power-outlets": [
137
+ "dcim/cable-terminations",
138
+ "dcim/devices",
139
+ "dcim/modules",
140
+ "dcim/power-ports",
141
+ "extras/tags",
142
+ ],
143
+ "dcim/power-panels": ["dcim/locations", "dcim/sites", "extras/tags"],
144
+ "dcim/power-port-templates": ["dcim/device-types", "dcim/module-types"],
145
+ "dcim/power-ports": ["dcim/cable-terminations", "dcim/devices", "dcim/modules", "extras/tags"],
146
+ "dcim/rack-reservations": ["dcim/racks", "extras/tags", "tenancy/tenants", "users/users"],
147
+ "dcim/rack-roles": ["extras/tags"],
148
+ "dcim/racks": [
149
+ "dcim/locations",
150
+ "dcim/rack-roles",
151
+ "dcim/sites",
152
+ "extras/tags",
153
+ "ipam/vlan-groups",
154
+ "tenancy/tenants",
155
+ ],
156
+ "dcim/rear-port-templates": ["dcim/device-types", "dcim/module-types"],
157
+ "dcim/rear-ports": ["dcim/cable-terminations", "dcim/devices", "dcim/modules", "extras/tags"],
158
+ "dcim/regions": ["extras/tags", "ipam/vlan-groups"],
159
+ "dcim/site-groups": ["extras/tags", "ipam/vlan-groups"],
160
+ "dcim/sites": [
161
+ "dcim/regions",
162
+ "dcim/site-groups",
163
+ "extras/tags",
164
+ "ipam/asns",
165
+ "ipam/vlan-groups",
166
+ "tenancy/tenants",
167
+ ],
168
+ "dcim/virtual-chassis": ["dcim/devices", "extras/tags"],
169
+ "dcim/virtual-device-contexts": ["dcim/devices", "extras/tags", "tenancy/tenants"],
170
+ "extras/config-contexts": [
171
+ "dcim/device-roles",
172
+ "dcim/device-types",
173
+ "dcim/locations",
174
+ "dcim/platforms",
175
+ "dcim/regions",
176
+ "dcim/site-groups",
177
+ "dcim/sites",
178
+ "extras/tags",
179
+ "tenancy/tenant-groups",
180
+ "tenancy/tenants",
181
+ "virtualization/cluster-groups",
182
+ "virtualization/cluster-types",
183
+ "virtualization/clusters",
184
+ ],
185
+ "extras/config-templates": ["extras/tags"],
186
+ "extras/content-types": [],
187
+ "extras/custom-fields": ["extras/content-types"],
188
+ "extras/custom-links": ["extras/content-types"],
189
+ "extras/export-templates": ["extras/content-types"],
190
+ "extras/image-attachments": ["extras/content-types"],
191
+ "extras/journal-entries": ["extras/content-types", "extras/tags", "users/users"],
192
+ "extras/object-changes": ["users/users"],
193
+ "extras/saved-filters": ["extras/content-types", "users/users"],
194
+ "extras/tags": [],
195
+ "extras/webhooks": ["extras/content-types"],
196
+ "ipam/aggregates": ["extras/tags", "ipam/rirs", "tenancy/tenants"],
197
+ "ipam/asn-ranges": ["extras/tags", "ipam/rirs", "tenancy/tenants"],
198
+ "ipam/asns": ["extras/tags", "ipam/rirs", "tenancy/tenants"],
199
+ "ipam/fhrp-group-assignments": ["extras/content-types", "ipam/fhrp-groups"],
200
+ "ipam/fhrp-groups": ["extras/tags", "ipam/ip-addresses"],
201
+ "ipam/ip-addresses": ["extras/tags", "ipam/vrfs", "tenancy/tenants"],
202
+ "ipam/ip-ranges": ["extras/tags", "ipam/roles", "ipam/vrfs", "tenancy/tenants"],
203
+ "ipam/l2vpn-terminations": ["extras/tags", "ipam/l2vpns"],
204
+ "ipam/l2vpns": ["extras/tags", "ipam/route-targets", "tenancy/tenants"],
205
+ "ipam/prefixes": [
206
+ "dcim/sites",
207
+ "extras/tags",
208
+ "ipam/roles",
209
+ "ipam/vlans",
210
+ "ipam/vrfs",
211
+ "tenancy/tenants",
212
+ ],
213
+ "ipam/rirs": ["extras/tags"],
214
+ "ipam/roles": ["extras/tags"],
215
+ "ipam/route-targets": ["extras/tags", "tenancy/tenants"],
216
+ "ipam/service-templates": ["extras/tags"],
217
+ "ipam/services": [
218
+ "dcim/devices",
219
+ "extras/tags",
220
+ "ipam/ip-addresses",
221
+ "virtualization/virtual-machines",
222
+ ],
223
+ "ipam/vlan-groups": ["extras/content-types", "extras/tags"],
224
+ "ipam/vlans": [
225
+ "dcim/sites",
226
+ "extras/tags",
227
+ "ipam/l2vpn-terminations",
228
+ "ipam/roles",
229
+ "ipam/vlan-groups",
230
+ "tenancy/tenants",
231
+ ],
232
+ "ipam/vrfs": ["extras/tags", "ipam/route-targets", "tenancy/tenants"],
233
+ "tenancy/contact-assignments": [
234
+ "extras/content-types",
235
+ "tenancy/contact-roles",
236
+ "tenancy/contacts",
237
+ ],
238
+ "tenancy/contact-groups": ["extras/tags"],
239
+ "tenancy/contact-roles": ["extras/tags"],
240
+ "tenancy/contacts": ["extras/tags", "tenancy/contact-groups"],
241
+ "tenancy/tenant-groups": ["extras/tags"],
242
+ "tenancy/tenants": ["extras/tags", "tenancy/tenant-groups"],
243
+ "users/groups": [],
244
+ "users/permissions": ["extras/content-types", "users/groups", "users/users"],
245
+ "users/tokens": ["users/users"],
246
+ "users/users": [],
247
+ "virtualization/cluster-groups": ["extras/tags", "ipam/vlan-groups"],
248
+ "virtualization/cluster-types": ["extras/tags"],
249
+ "virtualization/clusters": [
250
+ "dcim/sites",
251
+ "extras/tags",
252
+ "ipam/vlan-groups",
253
+ "tenancy/tenants",
254
+ "virtualization/cluster-groups",
255
+ "virtualization/cluster-types",
256
+ ],
257
+ "virtualization/interfaces": [
258
+ "extras/tags",
259
+ "ipam/ip-addresses",
260
+ "ipam/l2vpn-terminations",
261
+ "ipam/vlans",
262
+ "ipam/vrfs",
263
+ "virtualization/virtual-machines",
264
+ ],
265
+ "virtualization/virtual-machines": [
266
+ "dcim/device-roles",
267
+ "dcim/devices",
268
+ "dcim/platforms",
269
+ "dcim/sites",
270
+ "extras/tags",
271
+ "tenancy/tenants",
272
+ "virtualization/clusters",
273
+ ],
274
+ "wireless/wireless-lan-groups": ["extras/tags"],
275
+ "wireless/wireless-lans": [
276
+ "extras/tags",
277
+ "ipam/vlans",
278
+ "tenancy/tenants",
279
+ "wireless/wireless-lan-groups",
280
+ ],
281
+ "wireless/wireless-links": ["extras/tags", "tenancy/tenants"],
282
+ }
283
+ """Models dependency for Netbox v3.5."""
@@ -9,286 +9,13 @@ from urllib.parse import ParseResult, urlencode, urlparse, parse_qs
9
9
  from vhelpers import vlist, vparam, vint
10
10
 
11
11
  from nbforager.exceptions import NbApiError
12
+ from nbforager.constants import DEPENDENT_MODELS
12
13
  from nbforager.types_ import LStr, LDAny, DDDLInt, LValue, LParam, LDList, DList, DLStr, ODLStr
13
14
  from nbforager.types_ import LTInt2, DAny, SeqStr, SStr, TValues, TLists, T2Str, T3Str, T3StrInt
14
15
 
15
- # Netbox v3.5
16
- DEPENDENT_MODELS: DLStr = {
17
- "circuits/circuit-terminations": [
18
- "circuits/circuits",
19
- "circuits/provider-networks",
20
- "dcim/cable-terminations",
21
- "dcim/sites",
22
- "extras/tags",
23
- ],
24
- "circuits/circuit-types": ["extras/tags"],
25
- "circuits/circuits": [
26
- "circuits/circuit-types",
27
- "circuits/provider-accounts",
28
- "circuits/providers",
29
- "extras/tags",
30
- "tenancy/tenants",
31
- ],
32
- "circuits/provider-accounts": ["circuits/providers", "extras/tags"],
33
- "circuits/provider-networks": ["circuits/providers", "extras/tags"],
34
- "circuits/providers": ["extras/tags", "ipam/asns"],
35
- "core/data-files": ["core/data-sources"],
36
- "core/data-sources": ["extras/tags"],
37
- "core/jobs": ["extras/content-types"],
38
- "dcim/cable-terminations": [
39
- "dcim/cables",
40
- "dcim/devices",
41
- "dcim/locations",
42
- "dcim/racks",
43
- "dcim/sites",
44
- ],
45
- "dcim/cables": ["extras/tags", "tenancy/tenants"],
46
- "dcim/console-port-templates": ["dcim/device-types", "dcim/module-types"],
47
- "dcim/console-ports": [
48
- "dcim/cable-terminations",
49
- "dcim/devices",
50
- "dcim/modules",
51
- "extras/tags",
52
- ],
53
- "dcim/console-server-port-templates": ["dcim/device-types", "dcim/module-types"],
54
- "dcim/console-server-ports": [
55
- "dcim/cable-terminations",
56
- "dcim/devices",
57
- "dcim/modules",
58
- "extras/tags",
59
- ],
60
- "dcim/device-bay-templates": ["dcim/device-types"],
61
- "dcim/device-bays": ["dcim/devices", "extras/tags"],
62
- "dcim/device-roles": ["extras/config-templates", "extras/tags"],
63
- "dcim/device-types": ["dcim/manufacturers", "extras/tags"],
64
- "dcim/devices": [
65
- "dcim/device-roles",
66
- "dcim/device-types",
67
- "dcim/locations",
68
- "dcim/platforms",
69
- "dcim/racks",
70
- "dcim/sites",
71
- "dcim/virtual-chassis",
72
- "extras/config-templates",
73
- "extras/tags",
74
- "tenancy/tenants",
75
- "virtualization/clusters",
76
- ],
77
- "dcim/front-port-templates": [
78
- "dcim/device-types",
79
- "dcim/module-types",
80
- "dcim/rear-port-templates",
81
- ],
82
- "dcim/front-ports": [
83
- "dcim/cable-terminations",
84
- "dcim/devices",
85
- "dcim/modules",
86
- "dcim/rear-ports",
87
- "extras/tags",
88
- ],
89
- "dcim/interface-templates": ["dcim/device-types", "dcim/module-types"],
90
- "dcim/interfaces": [
91
- "dcim/cable-terminations",
92
- "dcim/devices",
93
- "dcim/modules",
94
- "dcim/virtual-device-contexts",
95
- "extras/tags",
96
- "ipam/ip-addresses",
97
- "ipam/l2vpn-terminations",
98
- "ipam/vlans",
99
- "ipam/vrfs",
100
- "virtualization/interfaces",
101
- "wireless/wireless-lans",
102
- ],
103
- "dcim/inventory-item-roles": ["extras/tags"],
104
- "dcim/inventory-item-templates": [
105
- "dcim/device-types",
106
- "dcim/inventory-item-roles",
107
- "dcim/manufacturers",
108
- ],
109
- "dcim/inventory-items": [
110
- "dcim/devices",
111
- "dcim/inventory-item-roles",
112
- "dcim/manufacturers",
113
- "extras/tags",
114
- ],
115
- "dcim/locations": ["dcim/sites", "extras/tags", "ipam/vlan-groups", "tenancy/tenants"],
116
- "dcim/manufacturers": ["extras/tags"],
117
- "dcim/module-bay-templates": ["dcim/device-types"],
118
- "dcim/module-bays": ["dcim/devices", "extras/tags"],
119
- "dcim/module-types": ["dcim/manufacturers", "extras/tags"],
120
- "dcim/modules": ["dcim/devices", "dcim/module-bays", "dcim/module-types", "extras/tags"],
121
- "dcim/platforms": ["dcim/manufacturers", "extras/config-templates", "extras/tags"],
122
- "dcim/power-feeds": [
123
- "dcim/cable-terminations",
124
- "dcim/power-panels",
125
- "dcim/racks",
126
- "extras/tags",
127
- ],
128
- "dcim/power-outlet-templates": [
129
- "dcim/device-types",
130
- "dcim/module-types",
131
- "dcim/power-port-templates",
132
- ],
133
- "dcim/power-outlets": [
134
- "dcim/cable-terminations",
135
- "dcim/devices",
136
- "dcim/modules",
137
- "dcim/power-ports",
138
- "extras/tags",
139
- ],
140
- "dcim/power-panels": ["dcim/locations", "dcim/sites", "extras/tags"],
141
- "dcim/power-port-templates": ["dcim/device-types", "dcim/module-types"],
142
- "dcim/power-ports": ["dcim/cable-terminations", "dcim/devices", "dcim/modules", "extras/tags"],
143
- "dcim/rack-reservations": ["dcim/racks", "extras/tags", "tenancy/tenants", "users/users"],
144
- "dcim/rack-roles": ["extras/tags"],
145
- "dcim/racks": [
146
- "dcim/locations",
147
- "dcim/rack-roles",
148
- "dcim/sites",
149
- "extras/tags",
150
- "ipam/vlan-groups",
151
- "tenancy/tenants",
152
- ],
153
- "dcim/rear-port-templates": ["dcim/device-types", "dcim/module-types"],
154
- "dcim/rear-ports": ["dcim/cable-terminations", "dcim/devices", "dcim/modules", "extras/tags"],
155
- "dcim/regions": ["extras/tags", "ipam/vlan-groups"],
156
- "dcim/site-groups": ["extras/tags", "ipam/vlan-groups"],
157
- "dcim/sites": [
158
- "dcim/regions",
159
- "dcim/site-groups",
160
- "extras/tags",
161
- "ipam/asns",
162
- "ipam/vlan-groups",
163
- "tenancy/tenants",
164
- ],
165
- "dcim/virtual-chassis": ["dcim/devices", "extras/tags"],
166
- "dcim/virtual-device-contexts": ["dcim/devices", "extras/tags", "tenancy/tenants"],
167
- "extras/branchs": ["users/users"],
168
- "extras/config-contexts": [
169
- "dcim/device-roles",
170
- "dcim/device-types",
171
- "dcim/locations",
172
- "dcim/platforms",
173
- "dcim/regions",
174
- "dcim/site-groups",
175
- "dcim/sites",
176
- "extras/tags",
177
- "tenancy/tenant-groups",
178
- "tenancy/tenants",
179
- "virtualization/cluster-groups",
180
- "virtualization/cluster-types",
181
- "virtualization/clusters",
182
- ],
183
- "extras/config-templates": ["extras/tags"],
184
- "extras/content-types": [],
185
- "extras/custom-fields": ["extras/content-types"],
186
- "extras/custom-links": ["extras/content-types"],
187
- "extras/dashboards": ["users/users"],
188
- "extras/export-templates": ["extras/content-types"],
189
- "extras/image-attachments": ["extras/content-types"],
190
- "extras/journal-entries": ["extras/content-types", "extras/tags", "users/users"],
191
- "extras/object-changes": ["users/users"],
192
- "extras/saved-filters": ["extras/content-types", "users/users"],
193
- "extras/tagged-items": ["extras/content-types", "extras/tags"],
194
- "extras/tags": [],
195
- "extras/webhooks": ["extras/content-types"],
196
- "ipam/aggregates": ["extras/tags", "ipam/rirs", "tenancy/tenants"],
197
- "ipam/asn-ranges": ["extras/tags", "ipam/rirs", "tenancy/tenants"],
198
- "ipam/asns": ["extras/tags", "ipam/rirs", "tenancy/tenants"],
199
- "ipam/fhrp-group-assignments": ["extras/content-types", "ipam/fhrp-groups"],
200
- "ipam/fhrp-groups": ["extras/tags", "ipam/ip-addresses"],
201
- "ipam/ip-addresses": ["extras/tags", "ipam/vrfs", "tenancy/tenants"],
202
- "ipam/ip-ranges": ["extras/tags", "ipam/roles", "ipam/vrfs", "tenancy/tenants"],
203
- "ipam/l2vpn-terminations": ["extras/tags", "ipam/l2vpns"],
204
- "ipam/l2vpns": ["extras/tags", "ipam/route-targets", "tenancy/tenants"],
205
- "ipam/prefixes": [
206
- "dcim/sites",
207
- "extras/tags",
208
- "ipam/roles",
209
- "ipam/vlans",
210
- "ipam/vrfs",
211
- "tenancy/tenants",
212
- ],
213
- "ipam/rirs": ["extras/tags"],
214
- "ipam/roles": ["extras/tags"],
215
- "ipam/route-targets": ["extras/tags", "tenancy/tenants"],
216
- "ipam/service-templates": ["extras/tags"],
217
- "ipam/services": [
218
- "dcim/devices",
219
- "extras/tags",
220
- "ipam/ip-addresses",
221
- "virtualization/virtual-machines",
222
- ],
223
- "ipam/vlan-groups": ["extras/content-types", "extras/tags"],
224
- "ipam/vlans": [
225
- "dcim/sites",
226
- "extras/tags",
227
- "ipam/l2vpn-terminations",
228
- "ipam/roles",
229
- "ipam/vlan-groups",
230
- "tenancy/tenants",
231
- ],
232
- "ipam/vrfs": ["extras/tags", "ipam/route-targets", "tenancy/tenants"],
233
- "nb_config_checker/tasks": ["extras/tags", "users/users"],
234
- "social_django/user-social-auths": ["users/users"],
235
- "taggit/tagged-items": ["extras/content-types"],
236
- "tenancy/contact-assignments": [
237
- "extras/content-types",
238
- "tenancy/contact-roles",
239
- "tenancy/contacts",
240
- ],
241
- "tenancy/contact-groups": ["extras/tags"],
242
- "tenancy/contact-roles": ["extras/tags"],
243
- "tenancy/contacts": ["extras/tags", "tenancy/contact-groups"],
244
- "tenancy/tenant-groups": ["extras/tags"],
245
- "tenancy/tenants": ["extras/tags", "tenancy/tenant-groups"],
246
- "users/groups": [],
247
- "users/permissions": ["extras/content-types", "users/groups", "users/users"],
248
- "users/tokens": ["users/users"],
249
- "users/user-preferences": ["users/users"],
250
- "users/users": [],
251
- "virtualization/cluster-groups": ["extras/tags", "ipam/vlan-groups"],
252
- "virtualization/cluster-types": ["extras/tags"],
253
- "virtualization/clusters": [
254
- "dcim/sites",
255
- "extras/tags",
256
- "ipam/vlan-groups",
257
- "tenancy/tenants",
258
- "virtualization/cluster-groups",
259
- "virtualization/cluster-types",
260
- ],
261
- "virtualization/interfaces": [
262
- "extras/tags",
263
- "ipam/ip-addresses",
264
- "ipam/l2vpn-terminations",
265
- "ipam/vlans",
266
- "ipam/vrfs",
267
- "virtualization/virtual-machines",
268
- ],
269
- "virtualization/virtual-machines": [
270
- "dcim/device-roles",
271
- "dcim/devices",
272
- "dcim/platforms",
273
- "dcim/sites",
274
- "extras/tags",
275
- "tenancy/tenants",
276
- "virtualization/clusters",
277
- ],
278
- "wireless/wireless-lan-groups": ["extras/tags"],
279
- "wireless/wireless-lans": [
280
- "extras/tags",
281
- "ipam/vlans",
282
- "tenancy/tenants",
283
- "wireless/wireless-lan-groups",
284
- ],
285
- "wireless/wireless-links": ["extras/tags", "tenancy/tenants"],
286
- }
287
- """Models dependency for Netbox v3.5"""
288
-
289
16
 
290
17
  def dependency_ordered_paths(dependency: ODLStr = None) -> LStr:
291
- """Order paths based on dependencies. Models with the lowes count dependencies will be first.
18
+ """Order paths based on dependencies. Models with the lowes count of dependencies will be first.
292
19
 
293
20
  :param dependency: Dictionary representing dependencies,
294
21
  where key is the parent model and value is a list of child models.
@@ -10,6 +10,7 @@ from requests import Response
10
10
 
11
11
  from nbforager import helpers as h
12
12
  from nbforager.api.circuits import CircuitsAC
13
+ from nbforager.api.connector import Connector, GConnector
13
14
  from nbforager.api.core import CoreAC
14
15
  from nbforager.api.dcim import DcimAC
15
16
  from nbforager.api.extras import ExtrasAC
@@ -20,22 +21,10 @@ from nbforager.api.tenancy import TenancyAC
20
21
  from nbforager.api.users import UsersAC
21
22
  from nbforager.api.virtualization import VirtualizationAC
22
23
  from nbforager.api.wireless import WirelessAC
24
+ from nbforager.constants import APPS
23
25
  from nbforager.parser.nb_parser import NbParser
24
26
  from nbforager.types_ import ODLStr, ODDAny, DAny, LDAny, LStr, LT2Str
25
27
 
26
- APPS = (
27
- "circuits",
28
- "core",
29
- "dcim",
30
- "extras",
31
- "ipam",
32
- "plugins",
33
- "tenancy",
34
- "users",
35
- "virtualization",
36
- "wireless",
37
- )
38
-
39
28
 
40
29
  class NbApi:
41
30
  """NbApi, Python wrapper of Netbox REST API.
@@ -282,8 +271,17 @@ class NbApi:
282
271
  app_paths.append(path)
283
272
  return app_paths
284
273
 
285
- def connectors(self) -> ODDAny:
286
- """Return list of Connector instances ordered"""
274
+ def connectors(self) -> GConnector:
275
+ """Return generator of Connector instances ordered based on dependencies.
276
+ Connectors to models with the lowes count of dependencies will be first.
277
+
278
+ :return: Generator of Connector instances.
279
+ """
280
+ paths: LStr = h.dependency_ordered_paths()
281
+ for path in paths:
282
+ app, model = h.path_to_attrs(path)
283
+ connector: Connector = getattr(getattr(self, app), model)
284
+ yield connector
287
285
 
288
286
  def copy(self, **kwargs) -> NbApi:
289
287
  """Create a duplicate of the object.
@@ -2,7 +2,7 @@
2
2
 
3
3
  from datetime import datetime
4
4
  from pathlib import Path
5
- from typing import Any, Dict, List, Optional, Set, Tuple, Union, Sequence, TypeVar
5
+ from typing import Any, Dict, List, Optional, Sequence, Set, TypeVar, Tuple, Union
6
6
 
7
7
  # 1 level
8
8
  DAny = Dict[str, Any]
@@ -10,6 +10,7 @@ DInt = Dict[str, int]
10
10
  DObj = Dict[str, object]
11
11
  DStr = Dict[str, str]
12
12
  Int = int
13
+ IntStr = Union[int, str]
13
14
  LBool = List[bool]
14
15
  LInt = List[int]
15
16
  LPath = List[Path]
@@ -22,11 +23,10 @@ SInt = Set[int]
22
23
  SStr = Set[str]
23
24
  SeqStr = Sequence[str]
24
25
  Str = str
25
- IntStr = Union[int, str]
26
26
  T = TypeVar("T")
27
27
  T2Str = Tuple[str, str]
28
- T3StrInt = Tuple[str, str, int]
29
28
  T3Str = Tuple[str, str, str]
29
+ T3StrInt = Tuple[str, str, int]
30
30
  TLists = (list, set, tuple)
31
31
  TStr = Tuple[str, ...]
32
32
  TValues = (str, int, float)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "nbforager"
3
- version = "0.8.0"
3
+ version = "0.8.2"
4
4
  description = "Python package designed to assist in working with the Netbox REST API. The filter parameters are identical to those in the Web UI filter form. It replaces brief data with full information, and Netbox objects are represented as a recursive multidimensional dictionary."
5
5
  authors = ["Vladimirs Prusakovs <vladimir.prusakovs@gmail.com>"]
6
6
  readme = "README.rst"
@@ -19,7 +19,7 @@ classifiers = [
19
19
  homepage = "https://github.com/vladimirs-git/nbforager"
20
20
  repository = "https://github.com/vladimirs-git/nbforager"
21
21
  "Bug Tracker" = "https://github.com/vladimirs-git/nbforager/issues"
22
- "Download URL" = "https://github.com/vladimirs-git/nbforager/archive/refs/tags/0.8.0.tar.gz"
22
+ "Download URL" = "https://github.com/vladimirs-git/nbforager/archive/refs/tags/0.8.2.tar.gz"
23
23
 
24
24
  [tool.poetry.dependencies]
25
25
  python = "^3.11"
File without changes
File without changes
File without changes
File without changes