# Validator

The `Validator` class is the primary interface for data validation.

## Overview

```python
from pycharter import Validator

# Create from contract file
validator = Validator.from_file("user_contract.yaml")

# Validate data
result = validator.validate({"name": "Alice", "age": 30})

if result.is_valid:
    print(f"Valid: {result.data}")
else:
    print(f"Errors: {result.errors}")
```

## API Reference

::: pycharter.runtime_validator.Validator
    options:
      show_root_heading: true
      show_source: true
      members:
        - __init__
        - from_file
        - from_files
        - from_dir
        - from_dict
        - validate
        - validate_batch
        - get_model

## Factory Methods

### from_file

Create validator from a single contract file:

```python
validator = Validator.from_file("contracts/user.yaml")
```

### from_files

Create from separate files:

```python
validator = Validator.from_files(
    schema="schemas/user.yaml",
    coercion_rules="rules/coercion.yaml",
    validation_rules="rules/validation.yaml"
)
```

### from_dir

Create from a directory containing `schema.yaml`, `coercion_rules.yaml`, `validation_rules.yaml`:

```python
validator = Validator.from_dir("contracts/user/")
```

### from_dict

Create from dictionaries:

```python
validator = Validator.from_dict(
    schema={"type": "object", "properties": {...}},
    coercion_rules={"rules": {...}},
    validation_rules={"rules": {...}}
)
```

### From Metadata Store

```python
from pycharter import SQLiteMetadataStore

store = SQLiteMetadataStore("metadata.db")
store.connect()

validator = Validator(store=store, schema_id="user_schema_v1")
```

## ValidationResult

::: pycharter.runtime_validator.ValidationResult
    options:
      show_root_heading: true
      members:
        - is_valid
        - data
        - errors

## Examples

### Single Validation

```python
result = validator.validate({
    "name": "Alice",
    "email": "alice@example.com",
    "age": 30
})

if result.is_valid:
    user = result.data  # Pydantic model instance
    print(user.name)
else:
    for error in result.errors:
        print(f"{error['loc']}: {error['msg']}")
```

### Batch Validation

```python
records = [
    {"name": "Alice", "email": "alice@example.com"},
    {"name": "", "email": "invalid"},  # Invalid
    {"name": "Charlie", "email": "charlie@example.com"},
]

results = validator.validate_batch(records)

valid_records = [r.data for r in results if r.is_valid]
print(f"Valid: {len(valid_records)}/{len(records)}")
```

### Strict Mode

```python
from pydantic import ValidationError

try:
    result = validator.validate(data, strict=True)
    # If we get here, data is valid
except ValidationError as e:
    print(f"Validation failed: {e}")
```

### Getting the Model

```python
# Access the generated Pydantic model
UserModel = validator.get_model()

# Use it directly
user = UserModel(name="Alice", email="alice@example.com")

# Export schema
print(UserModel.model_json_schema())
```

## Convenience Functions

### validate_with_contract

Quick validation without creating a Validator instance:

```python
from pycharter import validate_with_contract

result = validate_with_contract("contract.yaml", data)
```

### validate_with_store

Validate using a schema from the metadata store:

```python
from pycharter import validate_with_store

result = validate_with_store(store, "user_schema_v1", data)
```

## See Also

- [Contracts Tutorial](../tutorials/contracts-validation.md)
- [Custom Validators Guide](../guides/custom-validators.md)
- [Pydantic Generator](pydantic-generator.md)
