Skip to content

nautobot.apps.api

Helpers for an app to implement a REST API.

nautobot.apps.api.APIRootView

Bases: NautobotAPIVersionMixin, APIRootView

Extends DRF's base APIRootView class to enforce user authentication.

nautobot.apps.api.BaseModelSerializer

Bases: OptInFieldsMixin, HyperlinkedModelSerializer

This base serializer implements common fields and logic for all ModelSerializers.

Namely, it:

  • defines the display field which exposes a human friendly value for the given object.
  • ensures that id field is always present on the serializer as well.
  • ensures that created and last_updated fields are always present if applicable to this model and serializer.
  • ensures that object_type field is always present on the serializer which represents the content-type of this serializer's associated model (e.g. "dcim.device"). This is required as the OpenAPI schema, using the PolymorphicProxySerializer class defined below, relies upon this field as a way to identify to the client which of several possible serializers are in use for a given attribute.
  • supports ?depth query parameter. It is passed in as nested_depth to the build_nested_field() function to enable the dynamic generation of nested serializers.

is_nested property

Return whether this is a nested serializer.

__init__(*args, force_csv=False, **kwargs)

Instantiate a BaseModelSerializer.

The force_csv kwarg allows you to force _is_csv_request() to evaluate True without passing a Request object, which is necessary to be able to export appropriately structured CSV from a Job that doesn't have a Request.

build_field(field_name, info, model_class, nested_depth)

Return a two tuple of (cls, kwargs) to build a serializer field with.

build_property_field(field_name, model_class)

Create a property field for model methods and properties.

build_relational_field(field_name, relation_info)

Override DRF's default relational-field construction to be app-aware.

build_url_field(field_name, model_class)

Override DRF's default 'url' field construction to be app-aware.

determine_view_options(request=None)

Determine view options to use for rendering the list and detail views associated with this serializer.

extend_field_names(fields, field_name, at_start=False, opt_in_only=False)

Prepend or append the given field_name to fields and optionally self.Meta.opt_in_fields as well.

get_additional_detail_view_tabs()

Retrieve definitions of non-default detail view tabs.

By default provides an "Advanced" tab containing self.advanced_tab_fields, but subclasses can override this to move additional serializer fields to this or other tabs.

Returns:

Type Description
dict

{<tab label>: [{<panel label>: {"fields": [<list of fields>]}, ...}, ...], ...}

get_display(instance)

Return either the display property of the instance or str(instance)

get_field_names(declared_fields, info)

Override get_field_names() to add some custom logic.

Assuming that we follow the pattern where fields = "__all__" for the vast majority of serializers in Nautobot, we do not strictly need to use this method to protect against inadvertently omitting standard fields likedisplay,created, andlast_updated`. However, we continue to do as a bit of redundant safety.

The other purpose of this method now is to manipulate the set of fields that "all" actually means as a way of excluding fields that we don't want to include by default for performance or data exposure reasons.

nautobot.apps.api.BulkDestroyModelMixin

Support bulk deletion of objects using the list endpoint for a model. Accepts a DELETE action with a list of one or more JSON objects, each specifying the UUID of an object to be deleted. For example:

DELETE /api/dcim/locations/ [ {"id": "3f01f169-49b9-42d5-a526-df9118635d62"}, {"id": "c27d6c5b-7ea8-41e7-b9dd-c065efd5d9cd"} ]

nautobot.apps.api.BulkUpdateModelMixin

Support bulk modification of objects using the list endpoint for a model. Accepts a PATCH action with a list of one or more JSON objects, each specifying the UUID of an object to be updated as well as the attributes to be set. For example:

PATCH /api/dcim/locations/ [ { "id": "1f554d07-d099-437d-8d48-7d6e35ec8fa3", "name": "New name" }, { "id": "1f554d07-d099-437d-8d48-7d6e65ec8fa3", "status": "planned" } ]

nautobot.apps.api.ChoiceField

Bases: Field

Represent a ChoiceField as {'value': , 'label': }. Accepts a single value on write.

:param choices: An iterable of choices in the form (value, key). :param allow_blank: Allow blank values in addition to the listed choices.

nautobot.apps.api.ContentTypeField

Bases: RelatedField

Represent a ContentType as '.'

nautobot.apps.api.CustomFieldModelSerializerMixin

Bases: ValidatedModelSerializer

Extends ModelSerializer to render any CustomFields and their values associated with an object.

get_field_names(declared_fields, info)

Ensure that "custom_fields" and "computed_fields" are included appropriately.

nautobot.apps.api.CustomFieldModelViewSet

Bases: ModelViewSet

Include the applicable set of CustomFields in the ModelViewSet context.

nautobot.apps.api.GetObjectCountsView

Bases: NautobotAPIVersionMixin, APIView

Enumerate the models listed on the Nautobot home page and return data structure containing verbose_name_plural, url and count.

nautobot.apps.api.ModelViewSet

Bases: NautobotAPIVersionMixin, BulkUpdateModelMixin, BulkDestroyModelMixin, ModelViewSetMixin, ModelViewSet

Extend DRF's ModelViewSet to support bulk update and delete functions.

nautobot.apps.api.ModelViewSetMixin

get_object()

Extend rest_framework.generics.GenericAPIView.get_object to allow "pk" lookups to use a composite-key.

initial(request, *args, **kwargs)

Runs anything that needs to occur prior to calling the method handler.

Override of internal Django Rest Framework API.

restrict_queryset(request, *args, **kwargs)

Restrict the view's queryset to allow only the permitted objects for the given request.

Subclasses (such as nautobot.extras.api.views.JobModelViewSet) may wish to override this.

Called by initial(), below.

nautobot.apps.api.MultipleChoiceJSONField

Bases: MultipleChoiceField

A MultipleChoiceField that renders the received value as a JSON-compatible list rather than a set.

__init__(**kwargs)

Overload default choices handling to also accept a callable.

nautobot.apps.api.NautobotAutoSchema

Bases: AutoSchema

Nautobot-specific extensions to drf-spectacular's AutoSchema.

is_bulk_action property

Custom property for convenience.

is_partial_action property

Custom property for convenience.

get_description()

Get the appropriate description for a given API endpoint.

By default, if a specific action doesn't have its own docstring, and neither does the view class, drf-spectacular will walk up the MRO of the view class until it finds a docstring, and use that. Most of our viewsets (for better or for worse) do not have docstrings, and so it'll find and use the generic docstring of the NautobotModelViewSet class, which isn't very useful to the end user. Instead of doing that, we only use the docstring of the view itself (ignoring its parent class docstrings), or if none exists, we make an attempt at rendering a basically accurate default description.

get_filter_backends()

Nautobot's custom bulk operations, even though they return a list of records, are NOT filterable.

get_operation_id()

Extend the base method to handle Nautobot's REST API bulk operations.

Without this extension, every one of our ModelViewSet classes will result in drf-spectacular complaining about operationId collisions, e.g. between DELETE /api/dcim/devices/ and DELETE /api/dcim/devices// would both get resolved to the same "dcim_devices_destroy" operation-id and this would make drf-spectacular complain.

With this extension, the bulk endpoints automatically get a different operation-id from the non-bulk endpoints.

get_request_serializer()

Return the request serializer (used for describing/parsing the request payload) for this endpoint.

We override the default drf-spectacular behavior for the case where the endpoint describes a write request with required data (PATCH, POST, PUT). In those cases we replace FooSerializer with a dynamically-defined WritableFooSerializer class in order to more accurately represent the available options on write.

We also override for the case where the endpoint is one of Nautobot's custom bulk API endpoints, which require a list of serializers as input, rather than a single one.

get_response_serializers()

Return the response serializer (used for describing the response payload) for this endpoint.

We override the default drf-spectacular behavior for the case where the endpoint describes a write request to a bulk endpoint, which returns a list of serializers, rather than a single one.

get_serializer_ref_name(serializer)

Get the serializer's ref_name Meta attribute if set, or else derive a ref_name automatically.

Based on drf_yasg.utils.get_serializer_ref_name().

get_writable_class(serializer, bulk=False)

Given a FooSerializer instance, look up or construct a [Bulk]WritableFooSerializer class if necessary.

If no [Bulk]WritableFooSerializer class is needed, returns None instead.

resolve_serializer(serializer, direction, bypass_extensions=False)

Re-add required id field on bulk_partial_update action.

drf-spectacular clears the required list for any partial serializers in its _map_basic_serializer(), but Nautobot bulk partial updates require the id field to be specified for each object to update.

nautobot.apps.api.NautobotCSVParser

Bases: BaseParser

Counterpart to NautobotCSVRenderer - import CSV data.

row_elements_to_data(counter, row, serializer)

Parse a single row of CSV data (represented as a dict) into a dict suitable for consumption by the serializer.

TODO: it would be more elegant if our serializer fields knew how to deserialize the CSV data themselves; could we then literally have the parser just return list(reader) and not need this function at all?

nautobot.apps.api.NautobotHyperlinkedRelatedField

Bases: WritableSerializerMixin, HyperlinkedRelatedField

Extend HyperlinkedRelatedField to include URL namespace-awareness, add 'object_type' field, and read composite-keys.

__init__(*args, **kwargs)

Override DRF's namespace-unaware default view_name logic for HyperlinkedRelatedField.

DRF defaults to '{model_name}-detail' instead of '{app_label}:{model_name}-detail'.

to_internal_value(data)

Convert potentially nested representation to a model instance.

to_representation(value)

Convert URL representation to a brief nested representation.

nautobot.apps.api.NautobotModelSerializer

Bases: RelationshipModelSerializerMixin, CustomFieldModelSerializerMixin, NotesSerializerMixin, ValidatedModelSerializer

Base class to use for serializers based on OrganizationalModel or PrimaryModel.

Can also be used for models derived from BaseModel, so long as they support custom fields, notes, and relationships.

nautobot.apps.api.NautobotModelViewSet

Bases: NotesViewSetMixin, CustomFieldModelViewSet

Base class to use for API ViewSets based on OrganizationalModel or PrimaryModel.

Can also be used for models derived from BaseModel, so long as they support Notes.

nautobot.apps.api.NotesSerializerMixin

Bases: BaseModelSerializer

Extend Serializer with a notes field.

get_field_names(declared_fields, info)

Ensure that fields includes "notes_url" field if applicable.

nautobot.apps.api.NotesViewSetMixin

CreateNotePermissions

Bases: TokenPermissions

As nautobot.core.api.authentication.TokenPermissions, but enforcing add_note permission.

notes(request, *args, **kwargs)

API methods for returning or creating notes on an object.

restrict_queryset(request, *args, **kwargs)

Apply "view" permissions on the POST /notes/ endpoint, otherwise as ModelViewSetMixin.

nautobot.apps.api.ObjectTypeField

Bases: CharField

Represent the ContentType of this serializer's model as ".".

__init__(*args, read_only=True, source='*', **kwargs)

Default read_only to True as this should never be a writable field.

to_representation(_value)

Get the content-type of this serializer's model.

Implemented this way because _value may be None when generating the schema.

nautobot.apps.api.OptInFieldsMixin

A serializer mixin that takes an additional opt_in_fields argument that controls which fields should be displayed.

fields property

Removes all serializer fields specified in a serializers opt_in_fields list that aren't specified in the include query parameter.

As an example, if the serializer specifies that opt_in_fields = ["computed_fields"] but computed_fields is not specified in the ?include query parameter, computed_fields will be popped from the list of fields.

nautobot.apps.api.OrderedDefaultRouter

Bases: DefaultRouter

get_api_root_view(api_urls=None)

Wrap DRF's DefaultRouter to return an alphabetized list of endpoints.

register(prefix, viewset, basename=None)

Override DRF's BaseRouter.register() to bypass an unnecessary restriction added in version 3.15.0.

(Reference: https://github.com/encode/django-rest-framework/pull/8438)

nautobot.apps.api.ReadOnlyModelViewSet

Bases: NautobotAPIVersionMixin, ModelViewSetMixin, ReadOnlyModelViewSet

Extend DRF's ReadOnlyModelViewSet to support queryset restriction.

nautobot.apps.api.RelationshipModelSerializerMixin

Bases: ValidatedModelSerializer

Extend ValidatedModelSerializer with a relationships field.

get_field_names(declared_fields, info)

Ensure that "relationships" is included as an opt-in field on root serializers.

nautobot.apps.api.SerializedPKRelatedField

Bases: PrimaryKeyRelatedField

Extends PrimaryKeyRelatedField to return a serialized object on read. This is useful for representing related objects in a ManyToManyField while still allowing a set of primary keys to be written.

nautobot.apps.api.TaggedModelSerializerMixin

Bases: BaseModelSerializer

get_field_names(declared_fields, info)

Ensure that 'tags' field is always present except on nested serializers.

nautobot.apps.api.TimeZoneSerializerField

Bases: TimeZoneSerializerField

Represents a time zone as a string.

nautobot.apps.api.TreeModelSerializerMixin

Bases: BaseModelSerializer

Add a tree_depth field to non-nested model serializers based on django-tree-queries.

get_field_names(declared_fields, info)

Ensure that "tree_depth" is included on root serializers only, as nested objects are not annotated.

get_tree_depth(obj)

The tree_depth is not a database field, but an annotation automatically added by django-tree-queries.

nautobot.apps.api.ValidatedModelSerializer

Bases: BaseModelSerializer

Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)

nautobot.apps.api.WritableNestedSerializer

Bases: BaseModelSerializer

Returns a nested representation of an object on read, but accepts either the nested representation or the primary key value on write operations.

Note that subclasses will always have a read-only object_type field, which represents the content-type of this serializer's associated model (e.g. "dcim.device"). This is required as the OpenAPI schema, using the PolymorphicProxySerializer class defined below, relies upon this field as a way to identify to the client which of several possible nested serializers are in use for a given attribute.

nautobot.apps.api.WritableSerializerMixin

WritableSerializerMixin provides the to_internal_value() function. The function provides the ability to write API requests that identify unique objects based on combinations of fields other than the primary key. e.g: "parent": { "location_type__parent": {"name": "Campus"}, "parent__name": "Campus-29" } vs "parent": "10dff139-7333-46b0-bef6-f6a5a7b5497c"

get_object(data, queryset)

Retrieve an unique object based on a dictionary of data attributes and raise errors accordingly if the object is not found.

get_queryset_filter_params(data, queryset)

Data could be a dictionary and an int (for the User model) or a str that represents the primary key. If it is a dictionary, we return it after remove non-filter fields. If it is a primary key, we return a dictionary object formatted like this {"pk": pk}

remove_non_filter_fields(filter_params)

Make output from a WritableSerializer "round-trip" capable by automatically stripping from the data any serializer fields that do not correspond to a specific model field

to_internal_value(data)

Return an object or a list of objects based on a dictionary of data attributes or an UUID.

nautobot.apps.api.dict_to_filter_params(d, prefix='')

Translate a dictionary of attributes to a nested set of parameters suitable for QuerySet filtering. For example:

{
    "name": "Foo",
    "rack": {
        "facility_id": "R101"
    }
}

Becomes:

{
    "name": "Foo",
    "rack__facility_id": "R101"
}

And can be employed as filter parameters:

Device.objects.filter(**dict_to_filter(attrs_dict))

nautobot.apps.api.dynamic_import(name)

Dynamically import a class from an absolute path string

nautobot.apps.api.get_api_version_serializer(serializer_choices, api_version)

Returns the serializer of an api_version

Parameters:

Name Type Description Default
serializer_choices tuple

list of SerializerVersions

required
api_version str

Request API version

required

Returns:

Type Description
Serializer

the serializer for the api_version if found in serializer_choices else None

nautobot.apps.api.get_serializer_for_model(model, prefix='')

Dynamically resolve and return the appropriate serializer for a model.

Raises:

Type Description
SerializerNotFound

if the requested serializer cannot be located.

nautobot.apps.api.get_view_name(view, suffix=None)

Derive the view name from its associated model, if it has one. Fall back to DRF's built-in get_view_name.

nautobot.apps.api.is_api_request(request)

Return True of the request is being made via the REST API.

nautobot.apps.api.rest_api_server_error(request, *args, **kwargs)

Handle exceptions and return a useful error message for REST API requests.

nautobot.apps.api.versioned_serializer_selector(obj, serializer_choices, default_serializer)

Returns appropriate serializer class depending on request api_version, and swagger_fake_view

Parameters:

Name Type Description Default
obj ViewSet instance
required
serializer_choices tuple

Tuple of SerializerVersions

required
default_serializer Serializer

Default Serializer class

required