Skip to content

Bug Report: ViewListResponse Validation Error with null labels #73

@briansumma

Description

@briansumma

Description

The client.metadata().get_views() method fails with Pydantic validation errors when processing the response from the Iconik API. The validation fails because the API returns null values for the label field in many view_fields objects, but the ViewField model expects label to be a valid string (not None).

Steps to Reproduce

  1. Initialize a PythonikClient instance
  2. Call client.metadata().get_views()
  3. Observe validation errors:
pydantic_core._pydantic_core.ValidationError: 82 validation errors for ViewListResponse
objects.0.view_fields.0.label
  Input should be a valid string [type=string_type, input_value=None, input_type=NoneType]

Expected Behavior

The get_views() method should successfully retrieve and parse the list of views from the API, even when label fields contain null values.

Actual Behavior

The method raises a Pydantic validation error with multiple validation errors related to null values in the label field of view_fields objects.

API Response Analysis

The API consistently returns null for many label fields in the view_fields list:

{
  "objects": [
    {
      "view_fields": [
        {
          "auto_set": null,
          "hide_if_not_set": null,
          "label": null,  // This is null but model requires string
          "mapped_field_name": null,
          "name": "description",
          "options": [],
          "read_only": null,
          "required": null,
          "source_url": null
        },
        // ...more fields with null labels
      ]
    }
  ]
}

Proposed Fix

Modify the ViewField class in pythonik/models/metadata/views.py to make the label field optional with a default value of None:

class ViewField(BaseModel):
    """Field configuration for a view."""
    name: str
    label: Optional[str] = None  # Changed from required to optional
    auto_set: Optional[bool] = False
    date_created: Optional[str] = None
    date_modified: Optional[str] = None
    description: Optional[str] = None
    external_id: Optional[str] = None
    field_type: Optional[str] = None
    hide_if_not_set: Optional[bool] = False
    is_block_field: Optional[bool] = False
    is_warning_field: Optional[bool] = False
    mapped_field_name: Optional[str] = None
    max_value: Optional[int] = None
    min_value: Optional[int] = None
    multi: Optional[bool] = False
    options: Optional[List[ViewOption]] = None
    read_only: Optional[bool] = False
    representative: Optional[bool] = False
    required: Optional[bool] = False
    sortable: Optional[bool] = False
    source_url: Optional[str] = None
    use_as_facet: Optional[bool] = False

Temporary Workaround

Until the fix is implemented, you can bypass the validation by directly accessing the API:

def get_raw_views():
    """Get views directly from the API without validation."""
    from pythonik.specs.metadata import MetadataSpec
    from pythonik.models.base import Response as PythonikResponse
    
    url = MetadataSpec.gen_url("views/")
    response = client.session.get(url, timeout=client.timeout)
    
    if response.ok:
        data = response.json()
        return PythonikResponse(response=response, data=data)
    else:
        return PythonikResponse(response=response, data=None)

# Use this instead of client.metadata().get_views()
views = get_raw_views()

Technical Details

  • Pydantic version: 2.4.2
  • Python version: 3.11.9
  • Pythonik version: 1.10.0

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions