Validation Engine
Validation is performed through SchemaModel.validate(). The engine package exposes
the result models the pipeline produces.
ValidationResult
nyctea.engine.results.ValidationResult
dataclass
Result of a validation run.
Source code in src/nyctea/engine/results.py
| @dataclass(frozen=True)
class ValidationResult:
"""Result of a validation run."""
data: pl.DataFrame | pl.LazyFrame
errors: pl.DataFrame
report: ValidationReport
|
ValidationReport
nyctea.engine.results.ValidationReport
Bases: BaseModel
Comprehensive validation outcome report.
Source code in src/nyctea/engine/results.py
| class ValidationReport(BaseModel):
"""Comprehensive validation outcome report."""
model_config = ConfigDict(extra="forbid")
rows_processed: int
rows_valid: int
on_failure: OnFailureBehavior
columns: dict[str, ColumnValidationStats] = Field(default_factory=dict)
def summary(self) -> str:
"""Return a human-readable summary."""
pct = (self.rows_valid / self.rows_processed * 100) if self.rows_processed else 0.0
lines = [
f"Validation Report (on_failure: {self.on_failure})",
f"Rows: {self.rows_valid}/{self.rows_processed} valid ({pct:.1f}%)",
"",
"Column Issues:",
]
for col_name, stats in self.columns.items():
if (
stats.nullified > 0
or stats.parse_failures > 0
or stats.check_failures > 0
or stats.coercion_failures > 0
):
lines.append(f" {col_name}:")
if stats.parse_failures:
lines.append(f" Parse failures: {stats.parse_failures}")
if stats.coercion_failures:
lines.append(f" Coercion failures: {stats.coercion_failures}")
if stats.check_failures:
lines.append(f" Check failures: {stats.check_failures}")
if stats.nullified:
lines.append(f" Nullified: {stats.nullified}")
lines.append(f" Final nulls: {stats.final_null_count}")
return "\n".join(lines)
|
summary()
Return a human-readable summary.
Source code in src/nyctea/engine/results.py
| def summary(self) -> str:
"""Return a human-readable summary."""
pct = (self.rows_valid / self.rows_processed * 100) if self.rows_processed else 0.0
lines = [
f"Validation Report (on_failure: {self.on_failure})",
f"Rows: {self.rows_valid}/{self.rows_processed} valid ({pct:.1f}%)",
"",
"Column Issues:",
]
for col_name, stats in self.columns.items():
if (
stats.nullified > 0
or stats.parse_failures > 0
or stats.check_failures > 0
or stats.coercion_failures > 0
):
lines.append(f" {col_name}:")
if stats.parse_failures:
lines.append(f" Parse failures: {stats.parse_failures}")
if stats.coercion_failures:
lines.append(f" Coercion failures: {stats.coercion_failures}")
if stats.check_failures:
lines.append(f" Check failures: {stats.check_failures}")
if stats.nullified:
lines.append(f" Nullified: {stats.nullified}")
lines.append(f" Final nulls: {stats.final_null_count}")
return "\n".join(lines)
|
ColumnValidationStats
nyctea.engine.results.ColumnValidationStats
Bases: BaseModel
Per-column validation statistics.
Source code in src/nyctea/engine/results.py
| class ColumnValidationStats(BaseModel):
"""Per-column validation statistics."""
model_config = ConfigDict(extra="forbid")
column_name: str
parse_failures: int = 0
coercion_failures: int = 0
check_failures: int = 0
nullified: int = Field(0, description="Values set to null due to failures")
final_null_count: int = Field(0, description="Total nulls in output")
original_null_count: int = Field(
0,
description="Nulls after column resolution and before frame and column transformations",
)
|
ErrorReportConfig
nyctea.engine.results.ErrorReportConfig
Bases: BaseModel
Configuration for error reporting detail level.
Source code in src/nyctea/engine/results.py
| class ErrorReportConfig(BaseModel):
"""Configuration for error reporting detail level."""
model_config = ConfigDict(extra="forbid")
mode: Literal["summary", "rows", "cells"] = Field(
"summary",
description=(
"Error reporting mode:\n"
"- 'summary': Column + check + count only (minimal)\n"
"- 'rows': Add row indices where failures occurred\n"
"- 'cells': Add row indices + actual values (maximum detail)"
),
)
limit: int | None = Field(
None,
ge=0,
description="Maximum number of error rows to return per column+check. None = unlimited.",
)
include_values: bool = Field(
True,
description="Include actual failing values in output (only applies to 'cells' mode)",
)
|