nautobot / pynautobot

Nautobot Python SDK
https://pynautobot.readthedocs.io/en/latest/index.html
Apache License 2.0
36 stars 32 forks source link

Unable to Get Computed Fields #20

Open jvanderaa opened 3 years ago

jvanderaa commented 3 years ago

New in 1.1.0 is computed fields. There should be an object endpoint to see the computed fields.

 import pynautobot

nautobot = pynautobot.api(url='https://demo.nautobot.com', token='yes')

device1 = nautobot.dcim.devices.all()[0]

dir(device1)

['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattr__',
 '__getattribute__',
 '__getitem__',
 '__getstate__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__iter__',
 '__key__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__setstate__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 '_add_cache',
 '_diff',
 '_endpoint_from_url',
 '_full_cache',
 '_init_cache',
 '_parse_values',
 'api',
 'asset_tag',
 'cluster',
 'comments',
 'config_context',
 'created',
 'custom_fields',
 'default_ret',
 'delete',
 'device_role',
 'device_type',
 'display',
 'endpoint',
 'face',
 'full_details',
 'has_details',
 'id',
 'last_updated',
 'local_context_data',
 'local_context_schema',
 'name',
 'napalm',
 'parent_device',
 'platform',
 'position',
 'primary_ip',
 'primary_ip4',
 'primary_ip6',
 'rack',
 'save',
 'serial',
 'serialize',
 'site',
 'status',
 'tags',
 'tenant',
 'update',
 'url',
 'vc_position',
 'vc_priority',
 'virtual_chassis']

I would anticipate that there should be computed fields showing up here in the same way local_context_data does.

jvanderaa commented 3 years ago

@jfach

jvanderaa commented 3 years ago

Also not in the platform itself, where the web UI has it:

In [11]: platform = nautobot.dcim.platforms.all()[0]

In [12]: platform
Out[12]: Arista EOS

In [13]: dir(platform)
Out[13]: 
['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattr__',
 '__getattribute__',
 '__getitem__',
 '__getstate__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__iter__',
 '__key__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__setstate__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 '_add_cache',
 '_diff',
 '_endpoint_from_url',
 '_full_cache',
 '_init_cache',
 '_parse_values',
 'api',
 'created',
 'custom_fields',
 'default_ret',
 'delete',
 'description',
 'device_count',
 'display',
 'endpoint',
 'full_details',
 'has_details',
 'id',
 'last_updated',
 'manufacturer',
 'name',
 'napalm_args',
 'napalm_driver',
 'save',
 'serialize',
 'slug',
 'update',
 'url',
 'virtualmachine_count']

In [14]: platform.custom_fields
Out[14]: {}
jmcgill298 commented 3 years ago

This is because computed fields are not provided by default.

https://nautobot.readthedocs.io/en/latest/additional-features/computed-fields/#computed-fields-and-the-rest-api

jvanderaa commented 3 years ago

Agreed. So we need to be able to provide this as an option. Do we have a method to do so?

jmcgill298 commented 3 years ago

There is not currently an interface for grabbing fields excluded by the Serializer

jvanderaa commented 3 years ago

Makes sense. So to use this, should we look to have Nautobot move this?

glennmatthews commented 3 years ago

It would be good for pynautobot to have an option to specify custom query parameters in order to support this as well as other such use cases - for example I have a plugin under development where there's a custom ?include_inheritance REST API query parameter that also influences the serializer's behavior - a general solution here would enable pynautobot to readily handle that case as well.

dgarros commented 3 years ago

I think it's already working, I was able to query some computed fields with the current version of pynautobot

>>> import pynautobot
>>> nautobot = pynautobot.api( url="https://demo.nautobot.com/", token="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
>>>
>>> intf = nautobot.dcim.interfaces.filter(device="ams01-edge-01", name="Ethernet1/1", include="computed_fields")[0]
>>> intf.computed_fields.ntc_description
'peer=ams01-edge-02 | peer_intf=Ethernet1/1 | peer_role=edge'

The only thing is that computed_fields is automatically converted into an object which makes it hard to iterate over the values and it is not consistent with the custom_fields that are being returned as a dict

jmcgill298 commented 3 years ago

IMO, that is pretty hacky. It should also work with the get() method.