Guides
Custom Rules Guide
Learn how to write custom deterministic data quality validation rules
Featuresmith is fully extensible. You can add your own deterministic rules by extending the BaseRule interface and registering them with the Rule Engine.
The BaseRule Interface
All rules must extend BaseRule and implement the following properties and method:
id: A unique dotted identifier (e.g.,statistical.zero_variance).name: A short human-readable rule title.description: What the rule flags.category: The group category (quality,statistical, orleakage).severity: The default finding severity as a string ("info","warning", or"critical").enabled_by_default: Whether the rule runs by default in the engine.evaluate(profile: ProfileResult) -> list[RuleFinding]: The core audit logic.
Custom Rule Implementation
Here is a complete rule that flags numeric columns with zero standard deviation (constant-value columns), using the real BaseRule API and the NumericProfile output of the profiling engine:
python
from featuresmith.core.profile_result import ProfileResultfrom featuresmith.core.rule_finding import RuleFindingfrom featuresmith.rules.base import BaseRuleclass ZeroVarianceRule(BaseRule): """Custom rule to detect numeric columns with zero variance.""" @property def id(self) -> str: return "statistical.zero_variance" @property def name(self) -> str: return "Zero Variance Columns" @property def description(self) -> str: return "Flags numeric columns whose standard deviation is zero." @property def category(self) -> str: return "statistical" @property def severity(self) -> str: return "warning" @property def enabled_by_default(self) -> bool: return True def evaluate(self, profile: ProfileResult) -> list[RuleFinding]: findings: list[RuleFinding] = [] for col_name, num_prof in profile.numeric_profiles.items(): if num_prof.std_dev == 0.0: findings.append( RuleFinding( rule_id=self.id, rule_name=self.name, category=self.category, severity=self.severity, column_name=col_name, title=f"Zero variance in column '{col_name}'", description=( f"Column '{col_name}' has a standard deviation " f"of 0.0 (no variance)." ), evidence={ "std_dev": num_prof.std_dev, "unique_count": num_prof.unique_count, }, confidence=1.0, ) ) return findingsEvaluating Custom Rules
You can run the rule directly against a computed profile:
python
import featuresmith as fsdataset = fs.load("data.csv")profile = fs.profile(dataset)rule = ZeroVarianceRule()findings = rule.evaluate(profile)for finding in findings: print(f"[{finding.severity}] {finding.title} in {finding.column_name}")To run your custom rule inside the Rule Engine (for example alongside the built-ins through fs.analyze()), register it in a RuleRegistry and pass the registry to a RuleEngine:
python
from featuresmith.rules.engine import RuleEnginefrom featuresmith.rules.registry import RuleRegistry, default_registry# Start from the built-in rules and add your custom ruleregistry = RuleRegistry([*default_registry().list_rules(), ZeroVarianceRule()])engine = RuleEngine(registry=registry)result = engine.run( profile, target_column="churn", enabled_rules=["statistical.zero_variance"],)print(f"Executed {len(result.executed_rules)} rule(s): {result.executed_rules}")print(f"Failed: {result.failed_rules}")