Configuration Validation

Validation helpers for plugin configuration dataclasses

Schema Metadata Constants

Constants for field metadata keys used in dataclass configuration. These enable validation and are compatible with JSON schema generation for UI form builders.

Field Validation

Functions for validating field values against metadata constraints.


source

validate_field_value


def validate_field_value(
    value:Any, # Value to validate
    metadata:Dict, # Field metadata containing constraints
    field_name:str='', # Field name for error messages
)->Tuple: # (is_valid, error_message)

Validate a value against field metadata constraints.


source

validate_config


def validate_config(
    config:Any, # Configuration dataclass instance to validate
)->Tuple: # (is_valid, error_message)

Validate all fields in a configuration dataclass against their metadata constraints.

Dataclass Configuration Utilities

These functions provide utilities for working with dataclass-based plugin configurations.


source

config_to_dict


def config_to_dict(
    config:Any, # Configuration dataclass instance
)->Dict: # Dictionary representation of the configuration

Convert a configuration dataclass instance to a dictionary.

Converts a dataclass configuration instance to a dictionary for serialization or passing to other systems. Also accepts dict input for passthrough convenience.


source

dict_to_config


def dict_to_config(
    config_class:Type, # Configuration dataclass type
    data:Optional=None, # Dictionary with configuration values
    validate:bool=False, # Whether to validate against metadata constraints
)->T: # Instance of the configuration dataclass

Create a configuration dataclass instance from a dictionary.


source

extract_defaults


def extract_defaults(
    config_class:Type, # Configuration dataclass type
)->Dict: # Default values from the dataclass

Extract default values from a configuration dataclass type.

JSON Schema Conversion

Functions for converting dataclass configurations to JSON Schema format, enabling automatic form generation in UIs.


source

dataclass_to_jsonschema


def dataclass_to_jsonschema(
    cls:type, # Dataclass with field metadata
)->Dict: # JSON schema dictionary

Convert a dataclass to a JSON schema for form generation.

# Test _python_type_to_json_type
from typing import List, Optional

assert _python_type_to_json_type(str) == {"type": "string"}
assert _python_type_to_json_type(int) == {"type": "integer"}
assert _python_type_to_json_type(float) == {"type": "number"}
assert _python_type_to_json_type(bool) == {"type": "boolean"}
assert _python_type_to_json_type(List[str]) == {"type": "array", "items": {"type": "string"}}

optional_result = _python_type_to_json_type(Optional[int])
assert optional_result["type"] == ["integer", "null"]

print("Type conversion tests passed")
Type conversion tests passed
# Test dataclass_to_jsonschema using ExampleConfig defined below
# (This test runs after the ExampleConfig is defined in the notebook)
def _test_jsonschema():
    """Test JSON schema generation with ExampleConfig."""
    schema = dataclass_to_jsonschema(ExampleConfig)
    
    # Check structure
    assert schema["name"] == "ExampleConfig"
    assert schema["type"] == "object"
    assert "properties" in schema
    
    # Check field properties
    assert schema["properties"]["model"]["type"] == "string"
    assert schema["properties"]["model"]["title"] == "Model"
    assert schema["properties"]["model"]["enum"] == ["tiny", "base", "small", "medium", "large"]
    assert schema["properties"]["model"]["default"] == "base"
    
    assert schema["properties"]["temperature"]["type"] == "number"
    assert schema["properties"]["temperature"]["minimum"] == 0.0
    assert schema["properties"]["temperature"]["maximum"] == 1.0
    
    assert schema["properties"]["batch_size"]["type"] == "integer"
    assert schema["properties"]["enabled"]["type"] == "boolean"
    assert schema["properties"]["tags"]["type"] == "array"
    
    print("dataclass_to_jsonschema tests passed")
    return schema

Example: Working with Configuration Dataclasses

from dataclasses import dataclass, field
from typing import List

@dataclass
class ExampleConfig:
    """Example configuration dataclass with metadata constraints."""
    model:str = field(
        default="base",
        metadata={
            SCHEMA_TITLE: "Model",
            SCHEMA_DESC: "Model size to use",
            SCHEMA_ENUM: ["tiny", "base", "small", "medium", "large"]
        }
    )
    temperature:float = field(
        default=0.0,
        metadata={
            SCHEMA_TITLE: "Temperature",
            SCHEMA_DESC: "Sampling temperature",
            SCHEMA_MIN: 0.0,
            SCHEMA_MAX: 1.0
        }
    )
    batch_size:int = field(
        default=8,
        metadata={
            SCHEMA_TITLE: "Batch Size",
            SCHEMA_DESC: "Batch size for processing",
            SCHEMA_MIN: 1,
            SCHEMA_MAX: 32
        }
    )
    enabled:bool = field(
        default=True,
        metadata={SCHEMA_TITLE: "Enabled", SCHEMA_DESC: "Whether feature is enabled"}
    )
    tags:List[str] = field(
        default_factory=list,
        metadata={SCHEMA_TITLE: "Tags", SCHEMA_DESC: "Optional tags"}
    )

print("ExampleConfig dataclass defined with metadata constraints")
print(f"Fields: {[f.name for f in fields(ExampleConfig)]}")
ExampleConfig dataclass defined with metadata constraints
Fields: ['model', 'temperature', 'batch_size', 'enabled', 'tags']
# Test extract_defaults
defaults = extract_defaults(ExampleConfig)
print("Default values extracted from ExampleConfig:")
for k, v in defaults.items():
    print(f"  {k}: {v!r}")
Default values extracted from ExampleConfig:
  model: 'base'
  temperature: 0.0
  batch_size: 8
  enabled: True
  tags: []
# Test dict_to_config with validation
print("Creating config from dictionary:")

# Valid config
config1 = dict_to_config(ExampleConfig, {"model": "large", "temperature": 0.7}, validate=True)
print(f"Valid config: {config1}")

# Config with defaults (all valid)
config2 = dict_to_config(ExampleConfig, {}, validate=True)
print(f"Config with defaults: {config2}")

# Test validation failure - invalid enum
try:
    config_bad = dict_to_config(ExampleConfig, {"model": "invalid"}, validate=True)
except ValueError as e:
    print(f"\n✓ Caught invalid enum: {e}")

# Test validation failure - value below minimum
try:
    config_bad = dict_to_config(ExampleConfig, {"temperature": -0.5}, validate=True)
except ValueError as e:
    print(f"✓ Caught below minimum: {e}")

# Test validation failure - value above maximum
try:
    config_bad = dict_to_config(ExampleConfig, {"batch_size": 100}, validate=True)
except ValueError as e:
    print(f"✓ Caught above maximum: {e}")
Creating config from dictionary:
Valid config: ExampleConfig(model='large', temperature=0.7, batch_size=8, enabled=True, tags=[])
Config with defaults: ExampleConfig(model='base', temperature=0.0, batch_size=8, enabled=True, tags=[])

✓ Caught invalid enum: model: 'invalid' is not one of ['tiny', 'base', 'small', 'medium', 'large']
✓ Caught below minimum: temperature: -0.5 is less than minimum 0.0
✓ Caught above maximum: batch_size: 100 is greater than maximum 32
# Test validate_config directly
print("Testing validate_config:")

# Valid config
valid_config = ExampleConfig(model="small", temperature=0.5, batch_size=16)
is_valid, error = validate_config(valid_config)
print(f"Valid config: is_valid={is_valid}, error={error}")

# Invalid config - create without validation, then validate
invalid_config = ExampleConfig(model="invalid_model", temperature=0.5, batch_size=16)
is_valid, error = validate_config(invalid_config)
print(f"Invalid model: is_valid={is_valid}, error={error}")

# Test config_to_dict
print("\nConverting config to dictionary:")
config_dict = config_to_dict(valid_config)
print(f"As dictionary: {config_dict}")
Testing validate_config:
Valid config: is_valid=True, error=None
Invalid model: is_valid=False, error=model: 'invalid_model' is not one of ['tiny', 'base', 'small', 'medium', 'large']

Converting config to dictionary:
As dictionary: {'model': 'small', 'temperature': 0.5, 'batch_size': 16, 'enabled': True, 'tags': []}
# Test JSON schema generation
import json

schema = _test_jsonschema()
print("\nGenerated JSON Schema:")
print(json.dumps(schema, indent=2))
dataclass_to_jsonschema tests passed

Generated JSON Schema:
{
  "name": "ExampleConfig",
  "title": "ExampleConfig",
  "description": "Example configuration dataclass with metadata constraints.",
  "type": "object",
  "properties": {
    "model": {
      "type": "string",
      "title": "Model",
      "description": "Model size to use",
      "enum": [
        "tiny",
        "base",
        "small",
        "medium",
        "large"
      ],
      "default": "base"
    },
    "temperature": {
      "type": "number",
      "title": "Temperature",
      "description": "Sampling temperature",
      "minimum": 0.0,
      "maximum": 1.0,
      "default": 0.0
    },
    "batch_size": {
      "type": "integer",
      "title": "Batch Size",
      "description": "Batch size for processing",
      "minimum": 1,
      "maximum": 32,
      "default": 8
    },
    "enabled": {
      "type": "boolean",
      "title": "Enabled",
      "description": "Whether feature is enabled",
      "default": true
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "title": "Tags",
      "description": "Optional tags",
      "default": []
    }
  }
}