Exdantic.Runtime (exdantic v0.0.2)
View SourceRuntime schema generation and validation capabilities.
This module enables dynamic schema creation from field definitions at runtime,
supporting the DSPy pattern of pydantic.create_model("DSPyProgramOutputs", **fields)
.
Phase 5 Enhancement: Enhanced Runtime Schemas
Added support for enhanced runtime schemas with model validators and computed fields:
# Create enhanced schema with full validation pipeline
fields = [{:name, :string, [required: true]}, {:age, :integer, [optional: true]}]
# Model validators for cross-field validation
validators = [
fn data -> {:ok, %{data | name: String.trim(data.name)}} end,
{MyModule, :validate_age}
]
# Computed fields for derived values
computed_fields = [
{:display_name, :string, fn data -> {:ok, String.upcase(data.name)} end},
{:age_group, :string, {MyModule, :compute_age_group}}
]
# Create enhanced schema
schema = Runtime.create_enhanced_schema(fields,
title: "User Schema",
model_validators: validators,
computed_fields: computed_fields
)
# Validate with full pipeline
{:ok, result} = Runtime.validate_enhanced(%{name: " john ", age: 25}, schema)
# Result: %{name: "john", age: 25, display_name: "JOHN", age_group: "adult"}
Enhanced schemas support:
- Model validators (both named functions and anonymous functions)
- Computed fields (both named functions and anonymous functions)
- Full validation pipeline execution (field → model → computed)
- JSON Schema generation with enhanced metadata
- Integration with existing validation infrastructure
Basic Runtime Schemas
For simple use cases without enhanced features:
# Basic runtime schema
fields = [{:name, :string, [required: true]}, {:age, :integer, [optional: true]}]
schema = Runtime.create_schema(fields, title: "Basic User Schema")
{:ok, validated} = Runtime.validate(%{name: "John", age: 30}, schema)
# Result: %{name: "John", age: 30}
Schema Types
DynamicSchema
- Basic runtime schema with field validationEnhancedSchema
- Advanced runtime schema with model validators and computed fields
Phase 5 Migration Guide
Upgrading to Enhanced Runtime Schemas
Phase 5 adds enhanced runtime schemas while maintaining 100% backward compatibility with existing DynamicSchema usage.
Existing Code (Still Works)
# All existing runtime schema code continues to work unchanged
fields = [{:name, :string, [required: true]}]
schema = Exdantic.Runtime.create_schema(fields)
{:ok, result} = Exdantic.Runtime.validate(data, schema)
New Enhanced Features
# Create enhanced schema with model validators and computed fields
fields = [{:name, :string, [required: true]}]
validators = [fn data -> {:ok, %{data | name: String.trim(data.name)}} end]
computed = [{:display_name, :string, fn data -> {:ok, String.upcase(data.name)} end}]
enhanced_schema = Exdantic.Runtime.create_enhanced_schema(fields,
model_validators: validators,
computed_fields: computed
)
{:ok, result} = Exdantic.Runtime.validate_enhanced(data, enhanced_schema)
Unified Validation Interface
# Use Exdantic.Runtime.Validator for unified interface
alias Exdantic.Runtime.Validator
# Works with both DynamicSchema and EnhancedSchema
{:ok, result} = Validator.validate(data, any_runtime_schema)
json_schema = Validator.to_json_schema(any_runtime_schema)
info = Validator.schema_info(any_runtime_schema)
Breaking Changes
None. All existing code continues to work without modification.
New Dependencies
None. Phase 5 uses only existing Exdantic modules and standard library functions.
Performance Impact
- DynamicSchema validation performance unchanged
- EnhancedSchema adds minimal overhead for model validator and computed field execution
- JSON schema generation includes computed field metadata with negligible performance impact
Implementation Notes
Function Storage
Enhanced schemas store anonymous functions in a runtime function registry, ensuring they can be executed during validation while maintaining clean serialization for schema metadata.
Error Handling
Enhanced schemas provide comprehensive error handling:
- Field validation errors maintain existing behavior
- Model validator errors include clear context and function references
- Computed field errors specify which computation failed and why
- Type validation errors for computed field return values
JSON Schema Integration
Enhanced schemas generate JSON schemas that include:
- All regular fields with their types and constraints
- Computed fields marked as
readOnly: true
- Enhanced metadata (
x-enhanced-schema
,x-model-validators
,x-computed-fields
) - Full compatibility with existing JSON schema tooling
Memory Management
Runtime functions are stored efficiently with unique generated names to prevent conflicts. The function registry is cleaned up when the schema is garbage collected.
Testing Strategy
Phase 5 includes comprehensive tests covering:
- Basic enhanced schema creation and validation
- Model validator execution (named and anonymous functions)
- Computed field execution (named and anonymous functions)
- Error handling at each pipeline stage
- JSON schema generation with enhanced features
- Integration with existing validation infrastructure
- Performance benchmarks for enhanced vs basic schemas
All existing tests continue to pass, ensuring backward compatibility.
Summary
Functions
Creates an enhanced runtime schema with model validators and computed fields.
Creates an enhanced schema with Phase 6 integration features.
Creates a schema at runtime from field definitions.
Generates JSON Schema for enhanced runtime schemas.
Generates JSON Schema from a runtime schema.
Validates data against a runtime-created schema.
Validates data against an enhanced runtime schema.
Validates an enhanced schema with complete pipeline testing.
Types
Functions
@spec create_enhanced_schema([field_definition()], [schema_option()]) :: Exdantic.Runtime.EnhancedSchema.t()
Creates an enhanced runtime schema with model validators and computed fields.
This function provides a convenient way to create schemas with enhanced features similar to compile-time schemas but generated at runtime.
Parameters
field_definitions
- List of field definitionsopts
- Enhanced schema options
Options
:model_validators
- List of model validator functions:computed_fields
- List of computed field specifications- Standard options:
:title
,:description
,:strict
,:name
Examples
iex> fields = [{:name, :string, [required: true]}, {:age, :integer, [optional: true]}]
iex> validators = [fn data -> {:ok, %{data | name: String.trim(data.name)}} end]
iex> computed = [{:display_name, :string, fn data -> {:ok, String.upcase(data.name)} end}]
iex> schema = Exdantic.Runtime.create_enhanced_schema(fields,
...> model_validators: validators,
...> computed_fields: computed
...> )
%Exdantic.Runtime.EnhancedSchema{...}
@spec create_enhanced_schema_v6([field_definition()], [schema_option()]) :: Exdantic.Runtime.EnhancedSchema.t()
Creates an enhanced schema with Phase 6 integration features.
Phase 6 Enhancement: Complete integration with EnhancedResolver and validation pipeline.
Parameters
field_definitions
- Field definitionsopts
- Enhanced schema options with Phase 6 features
Phase 6 Options
:auto_optimize_for_provider
- Automatically optimize for LLM provider (default: nil):include_validation_metadata
- Include validation metadata in schema (default: false):dspy_compatible
- Ensure DSPy compatibility (default: false)- All existing options from previous phases
Examples
iex> schema = Exdantic.Runtime.create_enhanced_schema_v6(fields,
...> model_validators: validators,
...> computed_fields: computed,
...> auto_optimize_for_provider: :openai,
...> dspy_compatible: true
...> )
@spec create_schema([field_definition()], [schema_option()]) :: Exdantic.Runtime.DynamicSchema.t()
Creates a schema at runtime from field definitions.
Parameters
field_definitions
- List of field definitions in the format:{field_name, type}
{field_name, type, options}
opts
- Schema configuration options
Options
:title
- Schema title:description
- Schema description:strict
- Enable strict validation (default: false):name
- Schema name for references
Examples
iex> fields = [
...> {:name, :string, [required: true, min_length: 2]},
...> {:age, :integer, [optional: true, gt: 0]},
...> {:email, :string, [required: true, format: ~r/@/]}
...> ]
iex> schema = Exdantic.Runtime.create_schema(fields, title: "User Schema")
%Exdantic.Runtime.DynamicSchema{...}
@spec enhanced_to_json_schema( Exdantic.Runtime.EnhancedSchema.t(), keyword() ) :: map()
Generates JSON Schema for enhanced runtime schemas.
Parameters
enhanced_schema
- An EnhancedSchema structopts
- JSON Schema generation options
Returns
- JSON Schema map including computed field metadata
@spec to_json_schema( Exdantic.Runtime.DynamicSchema.t(), keyword() ) :: map()
Generates JSON Schema from a runtime schema.
Parameters
dynamic_schema
- A DynamicSchema structopts
- JSON Schema generation options
Returns
- JSON Schema map
Examples
iex> json_schema = Exdantic.Runtime.to_json_schema(schema)
%{"type" => "object", "properties" => %{...}}
@spec validate(map(), Exdantic.Runtime.DynamicSchema.t(), keyword()) :: {:ok, map()} | {:error, [Exdantic.Error.t()]}
Validates data against a runtime-created schema.
Parameters
data
- The data to validate (map)dynamic_schema
- A DynamicSchema structopts
- Validation options
Returns
{:ok, validated_data}
on success{:error, errors}
on validation failure
Examples
iex> data = %{name: "John", age: 30}
iex> Exdantic.Runtime.validate(data, schema)
{:ok, %{name: "John", age: 30}}
@spec validate_enhanced(map(), Exdantic.Runtime.EnhancedSchema.t(), keyword()) :: {:ok, map()} | {:error, [Exdantic.Error.t()]}
Validates data against an enhanced runtime schema.
Parameters
data
- The data to validate (map)enhanced_schema
- An EnhancedSchema structopts
- Validation options
Returns
{:ok, validated_data}
on success (includes computed fields){:error, errors}
on validation failure
Examples
iex> data = %{name: " John ", age: 30}
iex> Exdantic.Runtime.validate_enhanced(data, schema)
{:ok, %{name: "John", age: 30, display_name: "JOHN"}}
@spec validate_enhanced_v6(map(), Exdantic.Runtime.EnhancedSchema.t(), keyword()) :: {:ok, map()} | {:ok, map(), map()} | {:error, [Exdantic.Error.t()]}
Validates an enhanced schema with complete pipeline testing.
Phase 6 Enhancement: Comprehensive validation testing including all features.
Parameters
data
- Data to validateenhanced_schema
- Enhanced schemaopts
- Validation options with Phase 6 features
Phase 6 Options
:test_all_providers
- Test compatibility with all LLM providers (default: false):generate_performance_report
- Include performance metrics (default: false):validate_json_schema
- Validate generated JSON schema (default: false)
Returns
- Enhanced validation result with optional additional information