Warnings on schema generation for Writable Serializers #7911

Closed
opened 2025-12-29 20:29:53 +01:00 by adam · 1 comment
Owner

Originally created by @amhn on GitHub (Apr 14, 2023).

Originally assigned to: @arthanson on GitHub.

NetBox version

v3.5-beta

Python version

3.10

Steps to Reproduce

Generate schema using, e.g.

./netbox/manage.py spectacular --color --file schema.json --validate --format openapi-json

Expected Behavior

No warnings are displayed.

Observed Behavior

Currently several warnings are displayed for dynamically generated writable serializers:

Warning [InterfaceViewSet > WritableInterfaceSerializer]: unable to resolve type hint for function "l2vpn_termination". Consider using a type hint or @extend_schema_field. Defaulting to string.
Originally created by @amhn on GitHub (Apr 14, 2023). Originally assigned to: @arthanson on GitHub. ### NetBox version v3.5-beta ### Python version 3.10 ### Steps to Reproduce Generate schema using, e.g. ``` ./netbox/manage.py spectacular --color --file schema.json --validate --format openapi-json ``` ### Expected Behavior No warnings are displayed. ### Observed Behavior Currently several warnings are displayed for dynamically generated writable serializers: ``` Warning [InterfaceViewSet > WritableInterfaceSerializer]: unable to resolve type hint for function "l2vpn_termination". Consider using a type hint or @extend_schema_field. Defaulting to string. ```
adam added the status: acceptedtype: housekeepingbeta labels 2025-12-29 20:29:53 +01:00
adam closed this issue 2025-12-29 20:29:53 +01:00
Author
Owner

@amhn commented on GitHub (Apr 14, 2023):

As far as I can see this is because the fields are overwritten in NetboxAutoSchema. Because of that the type information and the read_only-Property seems to gets lost.

One possibility to get rid of the warning, is to drop read_only fields in the writable serializers:

diff --git a/netbox/core/api/schema.py b/netbox/core/api/schema.py
index 0b44a3d52..b5b21d67f 100644
--- a/netbox/core/api/schema.py
+++ b/netbox/core/api/schema.py
@@ -149,9 +149,12 @@ class NetBoxAutoSchema(AutoSchema):
 
     def get_writable_class(self, serializer):
         properties = {}
+        remove_fields = []
         fields = {} if hasattr(serializer, 'child') else serializer.fields
 
         for child_name, child in fields.items():
+            if 'read_only' in dir(child) and child.read_only:
+                remove_fields.append(child_name)
             if isinstance(child, (ChoiceField, WritableNestedSerializer)):
                 properties[child_name] = None
             elif isinstance(child, ManyRelatedField) and isinstance(child.child_relation, SerializedPKRelatedField):
@@ -165,7 +168,10 @@ class NetBoxAutoSchema(AutoSchema):
             meta_class = getattr(type(serializer), 'Meta', None)
             if meta_class:
                 ref_name = 'Writable' + self.get_serializer_ref_name(serializer)
-                writable_meta = type('Meta', (meta_class,), {'ref_name': ref_name})
+                fields = list(meta_class.fields)
+                for p in remove_fields:
+                    fields.remove(p)
+                writable_meta = type('Meta', (meta_class,), {'ref_name': ref_name, 'fields': fields})
                 properties['Meta'] = writable_meta
 
             self.writable_serializers[type(serializer)] = type(writable_name, (type(serializer),), properties)

This drops 2 fields from Writable*-components in the generated schema, but they were read_only anyway and should be in the model anyway

  • data_file inPatched WritableConfigContextRequest, WritableConfigContextRequest, WritableConfigTemplateRequest, PatchedWritableConfigTemplateRequest, PatchedWritableExportTemplateRequest, WritableExportTemplateRequest
  • wireless_link in PatchedWritableInterfaceRequest, WritableInterfaceRequest

Diff:

--- a/schema.yml
+++ b/schema.yml
@@ -93569,9 +93569,6 @@ components:
           type: integer
           nullable: true
           description: Remote data source
-        data_file:
-          type: integer
-          nullable: true
         data:
           type: object
           additionalProperties: {}
@@ -93602,9 +93599,6 @@ components:
           type: integer
           nullable: true
           description: Remote data source
-        data_file:
-          type: integer
-          nullable: true
         tags:
           type: array
           items:
@@ -94337,9 +94331,6 @@ components:
           type: integer
           nullable: true
           description: Remote data source
-        data_file:
-          type: integer
-          nullable: true
     PatchedWritableFHRPGroupAssignmentRequest:
       type: object
       description: Adds support for custom fields and tags.
@@ -94683,9 +94674,6 @@ components:
         mark_connected:
           type: boolean
           description: Treat as if a cable is connected
-        wireless_link:
-          type: integer
-          nullable: true
         wireless_lans:
           type: array
           items:
@@ -103563,9 +103551,6 @@ components:
           type: integer
           nullable: true
           description: Remote data source
-        data_file:
-          type: integer
-          nullable: true
         data:
           type: object
           additionalProperties: {}
@@ -103599,9 +103584,6 @@ components:
           type: integer
           nullable: true
           description: Remote data source
-        data_file:
-          type: integer
-          nullable: true
         tags:
           type: array
           items:
@@ -104438,9 +104420,6 @@ components:
           type: integer
           nullable: true
           description: Remote data source
-        data_file:
-          type: integer
-          nullable: true
       required:
       - content_types
       - name
 -104821,9 +104800,6 @@ components:
         mark_connected:
           type: boolean
           description: Treat as if a cable is connected
-        wireless_link:
-          type: integer
-          nullable: true
         wireless_lans:
           type: array
           items:
@amhn commented on GitHub (Apr 14, 2023): As far as I can see this is because the fields are overwritten in NetboxAutoSchema. Because of that the type information and the read_only-Property seems to gets lost. One possibility to get rid of the warning, is to drop read_only fields in the writable serializers: ```python diff --git a/netbox/core/api/schema.py b/netbox/core/api/schema.py index 0b44a3d52..b5b21d67f 100644 --- a/netbox/core/api/schema.py +++ b/netbox/core/api/schema.py @@ -149,9 +149,12 @@ class NetBoxAutoSchema(AutoSchema): def get_writable_class(self, serializer): properties = {} + remove_fields = [] fields = {} if hasattr(serializer, 'child') else serializer.fields for child_name, child in fields.items(): + if 'read_only' in dir(child) and child.read_only: + remove_fields.append(child_name) if isinstance(child, (ChoiceField, WritableNestedSerializer)): properties[child_name] = None elif isinstance(child, ManyRelatedField) and isinstance(child.child_relation, SerializedPKRelatedField): @@ -165,7 +168,10 @@ class NetBoxAutoSchema(AutoSchema): meta_class = getattr(type(serializer), 'Meta', None) if meta_class: ref_name = 'Writable' + self.get_serializer_ref_name(serializer) - writable_meta = type('Meta', (meta_class,), {'ref_name': ref_name}) + fields = list(meta_class.fields) + for p in remove_fields: + fields.remove(p) + writable_meta = type('Meta', (meta_class,), {'ref_name': ref_name, 'fields': fields}) properties['Meta'] = writable_meta self.writable_serializers[type(serializer)] = type(writable_name, (type(serializer),), properties) ``` This drops 2 fields from Writable*-components in the generated schema, but they were read_only anyway and should be in the model anyway - data_file inPatched WritableConfigContextRequest, WritableConfigContextRequest, WritableConfigTemplateRequest, PatchedWritableConfigTemplateRequest, PatchedWritableExportTemplateRequest, WritableExportTemplateRequest - wireless_link in PatchedWritableInterfaceRequest, WritableInterfaceRequest Diff: ``` yaml --- a/schema.yml +++ b/schema.yml @@ -93569,9 +93569,6 @@ components: type: integer nullable: true description: Remote data source - data_file: - type: integer - nullable: true data: type: object additionalProperties: {} @@ -93602,9 +93599,6 @@ components: type: integer nullable: true description: Remote data source - data_file: - type: integer - nullable: true tags: type: array items: @@ -94337,9 +94331,6 @@ components: type: integer nullable: true description: Remote data source - data_file: - type: integer - nullable: true PatchedWritableFHRPGroupAssignmentRequest: type: object description: Adds support for custom fields and tags. @@ -94683,9 +94674,6 @@ components: mark_connected: type: boolean description: Treat as if a cable is connected - wireless_link: - type: integer - nullable: true wireless_lans: type: array items: @@ -103563,9 +103551,6 @@ components: type: integer nullable: true description: Remote data source - data_file: - type: integer - nullable: true data: type: object additionalProperties: {} @@ -103599,9 +103584,6 @@ components: type: integer nullable: true description: Remote data source - data_file: - type: integer - nullable: true tags: type: array items: @@ -104438,9 +104420,6 @@ components: type: integer nullable: true description: Remote data source - data_file: - type: integer - nullable: true required: - content_types - name -104821,9 +104800,6 @@ components: mark_connected: type: boolean description: Treat as if a cable is connected - wireless_link: - type: integer - nullable: true wireless_lans: type: array items: ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#7911