We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Cable path tracing does not work with data imported by nautobot-netbox-importer (KeyError)
<!--
    NOTE: IF YOUR ISSUE DOES NOT FOLLOW THIS TEMPLATE, IT WILL BE CLOSED.

    This form is only for reporting reproducible bugs. If you need assistance
    with Nautobot installation, or if you have a general question, please start a
    discussion instead: https://github.com/nautobot/nautobot/discussions

    Please describe the environment in which you are running Nautobot. Be sure
    that you are running an unmodified instance of the latest stable release
    before submitting a bug report, and that any plugins have been disabled.
-->
### Environment
* Python version: any
* Nautobot version: 1.0.0b3

<!--
    Describe in detail the exact steps that someone else can take to reproduce
    this bug using the current stable release of Nautobot. Begin with the
    creation of any necessary database objects and call out every operation
    being performed explicitly. If reporting a bug in the REST API, be sure to
    reconstruct the raw HTTP request(s) being made: Don't rely on a client
    library such as pynautobot.
-->
### Steps to Reproduce
1. Install Nautobot 1.0.0b3
2. Install the `nautobot-netbox-importer` plugin
3. Import data from NetBox using the importer
4. In the Nautobot web UI, navigate to the Device detail view for a Device that has connected interfaces, and attempt to access the `Interfaces` tab.

<!-- What did you expect to happen? -->
### Expected Behavior

The page should load successfully, including cable traces for any connected interfaces.

<!-- What happened instead? -->
### Observed Behavior

Nautobot throws a KeyError:

```
  File "/usr/local/lib/python3.7/site-packages/nautobot/dcim/models/cables.py", line 465, in get_path
    path.append(prefetched[ct_id][object_id])
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `nautobot/dcim/utils.py`
Content:
```
1 import uuid
2 
3 from django.contrib.contenttypes.models import ContentType
4 
5 from nautobot.utilities.utils import hex_to_rgb, lighten_color, rgb_to_hex
6 
7 
8 def compile_path_node(ct_id, object_id):
9     return f"{ct_id}:{object_id}"
10 
11 
12 def decompile_path_node(repr):
13     ct_id, object_id = repr.split(":")
14     # The value is stored as a string, but the lookup later uses UUID objects as keys so we convert it now.
15     # Note that the content type ID is still an integer because we have no control over that model.
16     return int(ct_id), uuid.UUID(object_id, version=4)
17 
18 
19 def object_to_path_node(obj):
20     """
21     Return a representation of an object suitable for inclusion in a CablePath path. Node representation is in the
22     form <ContentType ID>:<Object ID>.
23     """
24     ct = ContentType.objects.get_for_model(obj)
25     return compile_path_node(ct.pk, obj.pk)
26 
27 
28 def path_node_to_object(repr):
29     """
30     Given the string representation of a path node, return the corresponding instance.
31     """
32     ct_id, object_id = decompile_path_node(repr)
33     ct = ContentType.objects.get_for_id(ct_id)
34     return ct.model_class().objects.get(pk=object_id)
35 
36 
37 def cable_status_color_css(record):
38     """
39     Given a record such as an Interface, return the CSS needed to apply appropriate coloring to it.
40     """
41     if not record.cable:
42         return ""
43     # The status colors are for use with labels and such, and tend to be quite bright.
44     # For this function we want a much milder, mellower color suitable as a row background.
45     base_color = record.cable.get_status_color().strip("#")
46     lighter_color = rgb_to_hex(*lighten_color(*hex_to_rgb(base_color), 0.75))
47     return f"background-color: #{lighter_color}"
48
```

Path: `nautobot/core/api/serializers.py`
Content:
```
1 import uuid
2 
3 from django.core.exceptions import (
4     FieldError,
5     MultipleObjectsReturned,
6     ObjectDoesNotExist,
7 )
8 from django.db.models import AutoField, ManyToManyField
9 from rest_framework import serializers
10 from rest_framework.exceptions import ValidationError
11 
12 from nautobot.utilities.utils import dict_to_filter_params
13 
14 
15 class ValidatedModelSerializer(serializers.ModelSerializer):
16     """
17     Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during
18     validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)
19     """
20 
21     def validate(self, data):
22 
23         # Remove custom fields data and tags (if any) prior to model validation
24         attrs = data.copy()
25         attrs.pop("custom_fields", None)
26         attrs.pop("tags", None)
27 
28         # Skip ManyToManyFields
29         for field in self.Meta.model._meta.get_fields():
30             if isinstance(field, ManyToManyField):
31                 attrs.pop(field.name, None)
32 
33         # Run clean() on an instance of the model
34         if self.instance is None:
35             instance = self.Meta.model(**attrs)
36         else:
37             instance = self.instance
38             for k, v in attrs.items():
39                 setattr(instance, k, v)
40         instance.full_clean()
41 
42         return data
43 
44 
45 class WritableNestedSerializer(serializers.ModelSerializer):
46     """
47     Returns a nested representation of an object on read, but accepts only a primary key on write.
48     """
49 
50     def to_internal_value(self, data):
51 
52         if data is None:
53             return None
54 
55         # Dictionary of related object attributes
56         if isinstance(data, dict):
57             params = dict_to_filter_params(data)
58             queryset = self.Meta.model.objects
59             try:
60                 return queryset.get(**params)
61             except ObjectDoesNotExist:
62                 raise ValidationError("Related object not found using the provided attributes: {}".format(params))
63             except MultipleObjectsReturned:
64                 raise ValidationError("Multiple objects match the provided attributes: {}".format(params))
65             except FieldError as e:
66                 raise ValidationError(e)
67 
68         queryset = self.Meta.model.objects
69         pk = None
70 
71         if isinstance(self.Meta.model._meta.pk, AutoField):
72             # PK is an int for this model. This is usually the User model
73             try:
74                 pk = int(data)
75             except (TypeError, ValueError):
76                 raise ValidationError(
77                     "Related objects must be referenced by ID or by dictionary of attributes. Received an "
78                     "unrecognized value: {}".format(data)
79                 )
80 
81         else:
82             # We assume a type of UUIDField for all other models
83 
84             # PK of related object
85             try:
86                 # Ensure the pk is a valid UUID
87                 pk = uuid.UUID(str(data), version=4)
88             except (TypeError, ValueError):
89                 raise ValidationError(
90                     "Related objects must be referenced by ID or by dictionary of attributes. Received an "
91                     "unrecognized value: {}".format(data)
92                 )
93 
94         try:
95             return queryset.get(pk=pk)
96         except ObjectDoesNotExist:
97             raise ValidationError("Related object not found using the provided ID: {}".format(pk))
98 
99 
100 class BulkOperationSerializer(serializers.Serializer):
101     id = serializers.CharField()  # This supports both UUIDs and numeric ID for the User model
102 
103 
104 #
105 # GraphQL, used by the openapi doc, not by the view
106 #
107 
108 
109 class GraphQLAPISerializer(serializers.Serializer):
110     query = serializers.CharField(required=True, help_text="GraphQL query")
111     variables = serializers.JSONField(required=False, help_text="Variables in JSON Format")
112
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/nautobot/core/api/serializers.py b/nautobot/core/api/serializers.py
--- a/nautobot/core/api/serializers.py
+++ b/nautobot/core/api/serializers.py
@@ -84,7 +84,7 @@
             # PK of related object
             try:
                 # Ensure the pk is a valid UUID
-                pk = uuid.UUID(str(data), version=4)
+                pk = uuid.UUID(str(data))
             except (TypeError, ValueError):
                 raise ValidationError(
                     "Related objects must be referenced by ID or by dictionary of attributes. Received an "
diff --git a/nautobot/dcim/utils.py b/nautobot/dcim/utils.py
--- a/nautobot/dcim/utils.py
+++ b/nautobot/dcim/utils.py
@@ -13,7 +13,7 @@
     ct_id, object_id = repr.split(":")
     # The value is stored as a string, but the lookup later uses UUID objects as keys so we convert it now.
     # Note that the content type ID is still an integer because we have no control over that model.
-    return int(ct_id), uuid.UUID(object_id, version=4)
+    return int(ct_id), uuid.UUID(object_id)
 
 
 def object_to_path_node(obj):

{"golden_diff": "diff --git a/nautobot/core/api/serializers.py b/nautobot/core/api/serializers.py\n--- a/nautobot/core/api/serializers.py\n+++ b/nautobot/core/api/serializers.py\n@@ -84,7 +84,7 @@\n             # PK of related object\n             try:\n                 # Ensure the pk is a valid UUID\n-                pk = uuid.UUID(str(data), version=4)\n+                pk = uuid.UUID(str(data))\n             except (TypeError, ValueError):\n                 raise ValidationError(\n                     \"Related objects must be referenced by ID or by dictionary of attributes. Received an \"\ndiff --git a/nautobot/dcim/utils.py b/nautobot/dcim/utils.py\n--- a/nautobot/dcim/utils.py\n+++ b/nautobot/dcim/utils.py\n@@ -13,7 +13,7 @@\n     ct_id, object_id = repr.split(\":\")\n     # The value is stored as a string, but the lookup later uses UUID objects as keys so we convert it now.\n     # Note that the content type ID is still an integer because we have no control over that model.\n-    return int(ct_id), uuid.UUID(object_id, version=4)\n+    return int(ct_id), uuid.UUID(object_id)\n \n \n def object_to_path_node(obj):\n", "issue": "Cable path tracing does not work with data imported by nautobot-netbox-importer (KeyError)\n<!--\r\n    NOTE: IF YOUR ISSUE DOES NOT FOLLOW THIS TEMPLATE, IT WILL BE CLOSED.\r\n\r\n    This form is only for reporting reproducible bugs. If you need assistance\r\n    with Nautobot installation, or if you have a general question, please start a\r\n    discussion instead: https://github.com/nautobot/nautobot/discussions\r\n\r\n    Please describe the environment in which you are running Nautobot. Be sure\r\n    that you are running an unmodified instance of the latest stable release\r\n    before submitting a bug report, and that any plugins have been disabled.\r\n-->\r\n### Environment\r\n* Python version: any\r\n* Nautobot version: 1.0.0b3\r\n\r\n<!--\r\n    Describe in detail the exact steps that someone else can take to reproduce\r\n    this bug using the current stable release of Nautobot. Begin with the\r\n    creation of any necessary database objects and call out every operation\r\n    being performed explicitly. If reporting a bug in the REST API, be sure to\r\n    reconstruct the raw HTTP request(s) being made: Don't rely on a client\r\n    library such as pynautobot.\r\n-->\r\n### Steps to Reproduce\r\n1. Install Nautobot 1.0.0b3\r\n2. Install the `nautobot-netbox-importer` plugin\r\n3. Import data from NetBox using the importer\r\n4. In the Nautobot web UI, navigate to the Device detail view for a Device that has connected interfaces, and attempt to access the `Interfaces` tab.\r\n\r\n<!-- What did you expect to happen? -->\r\n### Expected Behavior\r\n\r\nThe page should load successfully, including cable traces for any connected interfaces.\r\n\r\n<!-- What happened instead? -->\r\n### Observed Behavior\r\n\r\nNautobot throws a KeyError:\r\n\r\n```\r\n  File \"/usr/local/lib/python3.7/site-packages/nautobot/dcim/models/cables.py\", line 465, in get_path\r\n    path.append(prefetched[ct_id][object_id])\r\n```\r\n\n", "before_files": [{"content": "import uuid\n\nfrom django.contrib.contenttypes.models import ContentType\n\nfrom nautobot.utilities.utils import hex_to_rgb, lighten_color, rgb_to_hex\n\n\ndef compile_path_node(ct_id, object_id):\n    return f\"{ct_id}:{object_id}\"\n\n\ndef decompile_path_node(repr):\n    ct_id, object_id = repr.split(\":\")\n    # The value is stored as a string, but the lookup later uses UUID objects as keys so we convert it now.\n    # Note that the content type ID is still an integer because we have no control over that model.\n    return int(ct_id), uuid.UUID(object_id, version=4)\n\n\ndef object_to_path_node(obj):\n    \"\"\"\n    Return a representation of an object suitable for inclusion in a CablePath path. Node representation is in the\n    form <ContentType ID>:<Object ID>.\n    \"\"\"\n    ct = ContentType.objects.get_for_model(obj)\n    return compile_path_node(ct.pk, obj.pk)\n\n\ndef path_node_to_object(repr):\n    \"\"\"\n    Given the string representation of a path node, return the corresponding instance.\n    \"\"\"\n    ct_id, object_id = decompile_path_node(repr)\n    ct = ContentType.objects.get_for_id(ct_id)\n    return ct.model_class().objects.get(pk=object_id)\n\n\ndef cable_status_color_css(record):\n    \"\"\"\n    Given a record such as an Interface, return the CSS needed to apply appropriate coloring to it.\n    \"\"\"\n    if not record.cable:\n        return \"\"\n    # The status colors are for use with labels and such, and tend to be quite bright.\n    # For this function we want a much milder, mellower color suitable as a row background.\n    base_color = record.cable.get_status_color().strip(\"#\")\n    lighter_color = rgb_to_hex(*lighten_color(*hex_to_rgb(base_color), 0.75))\n    return f\"background-color: #{lighter_color}\"\n", "path": "nautobot/dcim/utils.py"}, {"content": "import uuid\n\nfrom django.core.exceptions import (\n    FieldError,\n    MultipleObjectsReturned,\n    ObjectDoesNotExist,\n)\nfrom django.db.models import AutoField, ManyToManyField\nfrom rest_framework import serializers\nfrom rest_framework.exceptions import ValidationError\n\nfrom nautobot.utilities.utils import dict_to_filter_params\n\n\nclass ValidatedModelSerializer(serializers.ModelSerializer):\n    \"\"\"\n    Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during\n    validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)\n    \"\"\"\n\n    def validate(self, data):\n\n        # Remove custom fields data and tags (if any) prior to model validation\n        attrs = data.copy()\n        attrs.pop(\"custom_fields\", None)\n        attrs.pop(\"tags\", None)\n\n        # Skip ManyToManyFields\n        for field in self.Meta.model._meta.get_fields():\n            if isinstance(field, ManyToManyField):\n                attrs.pop(field.name, None)\n\n        # Run clean() on an instance of the model\n        if self.instance is None:\n            instance = self.Meta.model(**attrs)\n        else:\n            instance = self.instance\n            for k, v in attrs.items():\n                setattr(instance, k, v)\n        instance.full_clean()\n\n        return data\n\n\nclass WritableNestedSerializer(serializers.ModelSerializer):\n    \"\"\"\n    Returns a nested representation of an object on read, but accepts only a primary key on write.\n    \"\"\"\n\n    def to_internal_value(self, data):\n\n        if data is None:\n            return None\n\n        # Dictionary of related object attributes\n        if isinstance(data, dict):\n            params = dict_to_filter_params(data)\n            queryset = self.Meta.model.objects\n            try:\n                return queryset.get(**params)\n            except ObjectDoesNotExist:\n                raise ValidationError(\"Related object not found using the provided attributes: {}\".format(params))\n            except MultipleObjectsReturned:\n                raise ValidationError(\"Multiple objects match the provided attributes: {}\".format(params))\n            except FieldError as e:\n                raise ValidationError(e)\n\n        queryset = self.Meta.model.objects\n        pk = None\n\n        if isinstance(self.Meta.model._meta.pk, AutoField):\n            # PK is an int for this model. This is usually the User model\n            try:\n                pk = int(data)\n            except (TypeError, ValueError):\n                raise ValidationError(\n                    \"Related objects must be referenced by ID or by dictionary of attributes. Received an \"\n                    \"unrecognized value: {}\".format(data)\n                )\n\n        else:\n            # We assume a type of UUIDField for all other models\n\n            # PK of related object\n            try:\n                # Ensure the pk is a valid UUID\n                pk = uuid.UUID(str(data), version=4)\n            except (TypeError, ValueError):\n                raise ValidationError(\n                    \"Related objects must be referenced by ID or by dictionary of attributes. Received an \"\n                    \"unrecognized value: {}\".format(data)\n                )\n\n        try:\n            return queryset.get(pk=pk)\n        except ObjectDoesNotExist:\n            raise ValidationError(\"Related object not found using the provided ID: {}\".format(pk))\n\n\nclass BulkOperationSerializer(serializers.Serializer):\n    id = serializers.CharField()  # This supports both UUIDs and numeric ID for the User model\n\n\n#\n# GraphQL, used by the openapi doc, not by the view\n#\n\n\nclass GraphQLAPISerializer(serializers.Serializer):\n    query = serializers.CharField(required=True, help_text=\"GraphQL query\")\n    variables = serializers.JSONField(required=False, help_text=\"Variables in JSON Format\")\n", "path": "nautobot/core/api/serializers.py"}], "after_files": [{"content": "import uuid\n\nfrom django.contrib.contenttypes.models import ContentType\n\nfrom nautobot.utilities.utils import hex_to_rgb, lighten_color, rgb_to_hex\n\n\ndef compile_path_node(ct_id, object_id):\n    return f\"{ct_id}:{object_id}\"\n\n\ndef decompile_path_node(repr):\n    ct_id, object_id = repr.split(\":\")\n    # The value is stored as a string, but the lookup later uses UUID objects as keys so we convert it now.\n    # Note that the content type ID is still an integer because we have no control over that model.\n    return int(ct_id), uuid.UUID(object_id)\n\n\ndef object_to_path_node(obj):\n    \"\"\"\n    Return a representation of an object suitable for inclusion in a CablePath path. Node representation is in the\n    form <ContentType ID>:<Object ID>.\n    \"\"\"\n    ct = ContentType.objects.get_for_model(obj)\n    return compile_path_node(ct.pk, obj.pk)\n\n\ndef path_node_to_object(repr):\n    \"\"\"\n    Given the string representation of a path node, return the corresponding instance.\n    \"\"\"\n    ct_id, object_id = decompile_path_node(repr)\n    ct = ContentType.objects.get_for_id(ct_id)\n    return ct.model_class().objects.get(pk=object_id)\n\n\ndef cable_status_color_css(record):\n    \"\"\"\n    Given a record such as an Interface, return the CSS needed to apply appropriate coloring to it.\n    \"\"\"\n    if not record.cable:\n        return \"\"\n    # The status colors are for use with labels and such, and tend to be quite bright.\n    # For this function we want a much milder, mellower color suitable as a row background.\n    base_color = record.cable.get_status_color().strip(\"#\")\n    lighter_color = rgb_to_hex(*lighten_color(*hex_to_rgb(base_color), 0.75))\n    return f\"background-color: #{lighter_color}\"\n", "path": "nautobot/dcim/utils.py"}, {"content": "import uuid\n\nfrom django.core.exceptions import (\n    FieldError,\n    MultipleObjectsReturned,\n    ObjectDoesNotExist,\n)\nfrom django.db.models import AutoField, ManyToManyField\nfrom rest_framework import serializers\nfrom rest_framework.exceptions import ValidationError\n\nfrom nautobot.utilities.utils import dict_to_filter_params\n\n\nclass ValidatedModelSerializer(serializers.ModelSerializer):\n    \"\"\"\n    Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during\n    validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)\n    \"\"\"\n\n    def validate(self, data):\n\n        # Remove custom fields data and tags (if any) prior to model validation\n        attrs = data.copy()\n        attrs.pop(\"custom_fields\", None)\n        attrs.pop(\"tags\", None)\n\n        # Skip ManyToManyFields\n        for field in self.Meta.model._meta.get_fields():\n            if isinstance(field, ManyToManyField):\n                attrs.pop(field.name, None)\n\n        # Run clean() on an instance of the model\n        if self.instance is None:\n            instance = self.Meta.model(**attrs)\n        else:\n            instance = self.instance\n            for k, v in attrs.items():\n                setattr(instance, k, v)\n        instance.full_clean()\n\n        return data\n\n\nclass WritableNestedSerializer(serializers.ModelSerializer):\n    \"\"\"\n    Returns a nested representation of an object on read, but accepts only a primary key on write.\n    \"\"\"\n\n    def to_internal_value(self, data):\n\n        if data is None:\n            return None\n\n        # Dictionary of related object attributes\n        if isinstance(data, dict):\n            params = dict_to_filter_params(data)\n            queryset = self.Meta.model.objects\n            try:\n                return queryset.get(**params)\n            except ObjectDoesNotExist:\n                raise ValidationError(\"Related object not found using the provided attributes: {}\".format(params))\n            except MultipleObjectsReturned:\n                raise ValidationError(\"Multiple objects match the provided attributes: {}\".format(params))\n            except FieldError as e:\n                raise ValidationError(e)\n\n        queryset = self.Meta.model.objects\n        pk = None\n\n        if isinstance(self.Meta.model._meta.pk, AutoField):\n            # PK is an int for this model. This is usually the User model\n            try:\n                pk = int(data)\n            except (TypeError, ValueError):\n                raise ValidationError(\n                    \"Related objects must be referenced by ID or by dictionary of attributes. Received an \"\n                    \"unrecognized value: {}\".format(data)\n                )\n\n        else:\n            # We assume a type of UUIDField for all other models\n\n            # PK of related object\n            try:\n                # Ensure the pk is a valid UUID\n                pk = uuid.UUID(str(data))\n            except (TypeError, ValueError):\n                raise ValidationError(\n                    \"Related objects must be referenced by ID or by dictionary of attributes. Received an \"\n                    \"unrecognized value: {}\".format(data)\n                )\n\n        try:\n            return queryset.get(pk=pk)\n        except ObjectDoesNotExist:\n            raise ValidationError(\"Related object not found using the provided ID: {}\".format(pk))\n\n\nclass BulkOperationSerializer(serializers.Serializer):\n    id = serializers.CharField()  # This supports both UUIDs and numeric ID for the User model\n\n\n#\n# GraphQL, used by the openapi doc, not by the view\n#\n\n\nclass GraphQLAPISerializer(serializers.Serializer):\n    query = serializers.CharField(required=True, help_text=\"GraphQL query\")\n    variables = serializers.JSONField(required=False, help_text=\"Variables in JSON Format\")\n", "path": "nautobot/core/api/serializers.py"}]}