Skip to content

Commit

Permalink
Merge pull request #197 from digitalocean/special-types
Browse files Browse the repository at this point in the history
Implements JsonField object
  • Loading branch information
Zach Moody authored Nov 16, 2019
2 parents f519b71 + 81082b1 commit 30b88f8
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 24 deletions.
43 changes: 22 additions & 21 deletions pynetbox/core/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@
from pynetbox.core.query import Request
from pynetbox.core.util import Hashabledict

# List of fields that contain a dict but are not to be converted into
# Record objects.
JSON_FIELDS = (
"custom_fields", "data", "config_context", "object_data"
)

# List of fields that are lists but should be treated as sets.
LIST_AS_SET = ("tags", "tagged_vlans")
Expand Down Expand Up @@ -61,6 +56,12 @@ def flatten_custom(custom_dict):
}


class JsonField(object):
"""Explicit field type for values that are not to be converted
to a Record object"""
_json_field = True


class Record(object):
"""Create python objects from netbox API responses.
Expand Down Expand Up @@ -235,25 +236,25 @@ def list_parser(list_item):
return list_item

for k, v in values.items():
if isinstance(v, dict):
lookup = getattr(self.__class__, k, None)
if k == "custom_fields" or hasattr(lookup, "_json_field"):
self._add_cache((k, v.copy()))
setattr(self, k, v)
continue
if lookup:
v = lookup(v, self.api, self.endpoint)
else:
v = self.default_ret(v, self.api, self.endpoint)
self._add_cache((k, v))

if k not in JSON_FIELDS:
if isinstance(v, dict):
lookup = getattr(self.__class__, k, None)
if lookup:
v = lookup(v, self.api, self.endpoint)
else:
v = self.default_ret(v, self.api, self.endpoint)
self._add_cache((k, v))

elif isinstance(v, list):
v = [list_parser(i) for i in v]
to_cache = list(v)
self._add_cache((k, to_cache))
elif isinstance(v, list):
v = [list_parser(i) for i in v]
to_cache = list(v)
self._add_cache((k, to_cache))

else:
self._add_cache((k, v))
else:
self._add_cache((k, v.copy()))
self._add_cache((k, v))
setattr(self, k, v)

def _compare(self):
Expand Down
4 changes: 3 additions & 1 deletion pynetbox/models/dcim.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
from pynetbox.core.response import Record
from pynetbox.core.response import Record, JsonField
from pynetbox.core.endpoint import RODetailEndpoint
from pynetbox.models.ipam import IpAddresses
from pynetbox.models.circuits import Circuits
Expand Down Expand Up @@ -44,6 +44,8 @@ class Devices(Record):
primary_ip = IpAddresses
primary_ip4 = IpAddresses
primary_ip6 = IpAddresses
local_context_data = JsonField
config_context = JsonField

@property
def napalm(self):
Expand Down
8 changes: 7 additions & 1 deletion pynetbox/models/extras.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
from pynetbox.core.response import Record
from pynetbox.core.response import Record, JsonField


class ConfigContexts(Record):
data = JsonField


class ObjectChanges(Record):
object_data = JsonField

def __str__(self):
return self.request_id
5 changes: 4 additions & 1 deletion tests/fixtures/dcim/device.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,11 @@
},
"primary_ip6": null,
"comments": "",
"local_context_data": {
"testing": "test"
},
"custom_fields": {},
"config_context": {
"test_key": "test_val"
}
}
}
1 change: 1 addition & 0 deletions tests/test_dcim.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ def test_get(self, mock):
self.assertTrue(isinstance(ret.primary_ip4, pynetbox.models.ipam.IpAddresses))
self.assertTrue(isinstance(ret.config_context, dict))
self.assertTrue(isinstance(ret.custom_fields, dict))
self.assertTrue(isinstance(ret.local_context_data, dict))
mock.assert_called_with(
'http://localhost:8000/api/{}/{}/1/'.format(
self.app,
Expand Down

0 comments on commit 30b88f8

Please sign in to comment.