truthound-dashboard 1.2.1__py3-none-any.whl → 1.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. truthound_dashboard/api/deps.py +28 -0
  2. truthound_dashboard/api/drift.py +1 -0
  3. truthound_dashboard/api/mask.py +164 -0
  4. truthound_dashboard/api/profile.py +11 -3
  5. truthound_dashboard/api/router.py +22 -0
  6. truthound_dashboard/api/scan.py +168 -0
  7. truthound_dashboard/api/schemas.py +13 -4
  8. truthound_dashboard/api/validations.py +33 -1
  9. truthound_dashboard/api/validators.py +85 -0
  10. truthound_dashboard/core/__init__.py +8 -0
  11. truthound_dashboard/core/phase5/activity.py +1 -1
  12. truthound_dashboard/core/services.py +457 -7
  13. truthound_dashboard/core/truthound_adapter.py +441 -26
  14. truthound_dashboard/db/__init__.py +6 -0
  15. truthound_dashboard/db/models.py +250 -1
  16. truthound_dashboard/schemas/__init__.py +52 -1
  17. truthound_dashboard/schemas/collaboration.py +1 -1
  18. truthound_dashboard/schemas/drift.py +118 -3
  19. truthound_dashboard/schemas/mask.py +209 -0
  20. truthound_dashboard/schemas/profile.py +45 -2
  21. truthound_dashboard/schemas/scan.py +312 -0
  22. truthound_dashboard/schemas/schema.py +30 -2
  23. truthound_dashboard/schemas/validation.py +60 -3
  24. truthound_dashboard/schemas/validators/__init__.py +59 -0
  25. truthound_dashboard/schemas/validators/aggregate_validators.py +238 -0
  26. truthound_dashboard/schemas/validators/anomaly_validators.py +723 -0
  27. truthound_dashboard/schemas/validators/base.py +263 -0
  28. truthound_dashboard/schemas/validators/completeness_validators.py +269 -0
  29. truthound_dashboard/schemas/validators/cross_table_validators.py +375 -0
  30. truthound_dashboard/schemas/validators/datetime_validators.py +253 -0
  31. truthound_dashboard/schemas/validators/distribution_validators.py +422 -0
  32. truthound_dashboard/schemas/validators/drift_validators.py +615 -0
  33. truthound_dashboard/schemas/validators/geospatial_validators.py +486 -0
  34. truthound_dashboard/schemas/validators/multi_column_validators.py +706 -0
  35. truthound_dashboard/schemas/validators/privacy_validators.py +531 -0
  36. truthound_dashboard/schemas/validators/query_validators.py +510 -0
  37. truthound_dashboard/schemas/validators/registry.py +318 -0
  38. truthound_dashboard/schemas/validators/schema_validators.py +408 -0
  39. truthound_dashboard/schemas/validators/string_validators.py +396 -0
  40. truthound_dashboard/schemas/validators/table_validators.py +412 -0
  41. truthound_dashboard/schemas/validators/uniqueness_validators.py +355 -0
  42. truthound_dashboard/schemas/validators.py +59 -0
  43. truthound_dashboard/static/assets/{index-BqXVFyqj.js → index-BCA8H1hO.js} +95 -95
  44. truthound_dashboard/static/assets/index-BNsSQ2fN.css +1 -0
  45. truthound_dashboard/static/assets/unmerged_dictionaries-CsJWCRx9.js +1 -0
  46. truthound_dashboard/static/index.html +2 -2
  47. {truthound_dashboard-1.2.1.dist-info → truthound_dashboard-1.3.0.dist-info}/METADATA +46 -11
  48. {truthound_dashboard-1.2.1.dist-info → truthound_dashboard-1.3.0.dist-info}/RECORD +51 -27
  49. truthound_dashboard/static/assets/index-o8qHVDte.css +0 -1
  50. truthound_dashboard/static/assets/unmerged_dictionaries-n_T3wZTf.js +0 -1
  51. {truthound_dashboard-1.2.1.dist-info → truthound_dashboard-1.3.0.dist-info}/WHEEL +0 -0
  52. {truthound_dashboard-1.2.1.dist-info → truthound_dashboard-1.3.0.dist-info}/entry_points.txt +0 -0
  53. {truthound_dashboard-1.2.1.dist-info → truthound_dashboard-1.3.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,318 @@
1
+ """Validator registry.
2
+
3
+ Central registry combining all validator categories with metadata and lookup functions.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from dataclasses import dataclass
9
+ from typing import Literal
10
+
11
+ from .base import ValidatorCategory, ValidatorDefinition
12
+
13
+ # Import all validator category modules
14
+ from .schema_validators import SCHEMA_VALIDATORS
15
+ from .completeness_validators import COMPLETENESS_VALIDATORS
16
+ from .uniqueness_validators import UNIQUENESS_VALIDATORS
17
+ from .distribution_validators import DISTRIBUTION_VALIDATORS
18
+ from .string_validators import STRING_VALIDATORS
19
+ from .datetime_validators import DATETIME_VALIDATORS
20
+ from .aggregate_validators import AGGREGATE_VALIDATORS
21
+ from .cross_table_validators import CROSS_TABLE_VALIDATORS
22
+ from .multi_column_validators import MULTI_COLUMN_VALIDATORS
23
+ from .query_validators import QUERY_VALIDATORS
24
+ from .table_validators import TABLE_VALIDATORS
25
+ from .geospatial_validators import GEOSPATIAL_VALIDATORS
26
+ from .drift_validators import DRIFT_VALIDATORS
27
+ from .anomaly_validators import ANOMALY_VALIDATORS
28
+ from .privacy_validators import PRIVACY_VALIDATORS
29
+
30
+
31
+ @dataclass
32
+ class CategoryInfo:
33
+ """Metadata for a validator category."""
34
+
35
+ value: str
36
+ label: str
37
+ description: str
38
+ icon: str | None = None
39
+ color: str | None = None
40
+ requires_extra: str | None = None
41
+ validator_count: int = 0
42
+
43
+
44
+ # Category metadata with UI information
45
+ CATEGORY_INFO: list[CategoryInfo] = [
46
+ # Core validators (no extra dependencies)
47
+ CategoryInfo(
48
+ value="schema",
49
+ label="Schema",
50
+ description="Validate structure, columns, and data types",
51
+ icon="layout",
52
+ color="#3b82f6", # blue
53
+ ),
54
+ CategoryInfo(
55
+ value="completeness",
56
+ label="Completeness",
57
+ description="Check for null values and missing data",
58
+ icon="check-circle",
59
+ color="#22c55e", # green
60
+ ),
61
+ CategoryInfo(
62
+ value="uniqueness",
63
+ label="Uniqueness",
64
+ description="Detect duplicates and validate keys",
65
+ icon="fingerprint",
66
+ color="#8b5cf6", # purple
67
+ ),
68
+ CategoryInfo(
69
+ value="distribution",
70
+ label="Distribution",
71
+ description="Validate value ranges and distributions",
72
+ icon="bar-chart",
73
+ color="#f59e0b", # amber
74
+ ),
75
+ # Format validators
76
+ CategoryInfo(
77
+ value="string",
78
+ label="String",
79
+ description="Pattern matching and format validation",
80
+ icon="type",
81
+ color="#06b6d4", # cyan
82
+ ),
83
+ CategoryInfo(
84
+ value="datetime",
85
+ label="Datetime",
86
+ description="Date/time format and range validation",
87
+ icon="calendar",
88
+ color="#ec4899", # pink
89
+ ),
90
+ # Statistical validators
91
+ CategoryInfo(
92
+ value="aggregate",
93
+ label="Aggregate",
94
+ description="Statistical aggregate checks (mean, sum, etc.)",
95
+ icon="calculator",
96
+ color="#6366f1", # indigo
97
+ ),
98
+ CategoryInfo(
99
+ value="drift",
100
+ label="Drift",
101
+ description="Distribution change detection between datasets",
102
+ icon="trending-up",
103
+ color="#ef4444", # red
104
+ requires_extra="drift",
105
+ ),
106
+ CategoryInfo(
107
+ value="anomaly",
108
+ label="Anomaly",
109
+ description="ML-based outlier and anomaly detection",
110
+ icon="alert-triangle",
111
+ color="#f97316", # orange
112
+ requires_extra="anomaly",
113
+ ),
114
+ # Relational validators
115
+ CategoryInfo(
116
+ value="cross_table",
117
+ label="Cross-Table",
118
+ description="Multi-table relationships and foreign keys",
119
+ icon="link",
120
+ color="#14b8a6", # teal
121
+ ),
122
+ CategoryInfo(
123
+ value="multi_column",
124
+ label="Multi-Column",
125
+ description="Column relationships and calculations",
126
+ icon="columns",
127
+ color="#84cc16", # lime
128
+ ),
129
+ CategoryInfo(
130
+ value="query",
131
+ label="Query",
132
+ description="Expression-based custom validation",
133
+ icon="code",
134
+ color="#a855f7", # violet
135
+ ),
136
+ # Domain validators
137
+ CategoryInfo(
138
+ value="table",
139
+ label="Table",
140
+ description="Table metadata and structure validation",
141
+ icon="table",
142
+ color="#0ea5e9", # sky
143
+ ),
144
+ CategoryInfo(
145
+ value="geospatial",
146
+ label="Geospatial",
147
+ description="Geographic coordinate validation",
148
+ icon="map-pin",
149
+ color="#10b981", # emerald
150
+ ),
151
+ CategoryInfo(
152
+ value="privacy",
153
+ label="Privacy",
154
+ description="PII detection and compliance (GDPR, CCPA)",
155
+ icon="shield",
156
+ color="#dc2626", # red-600
157
+ ),
158
+ ]
159
+
160
+
161
+ def _build_registry() -> list[ValidatorDefinition]:
162
+ """Build the complete validator registry from all categories."""
163
+ return [
164
+ *SCHEMA_VALIDATORS,
165
+ *COMPLETENESS_VALIDATORS,
166
+ *UNIQUENESS_VALIDATORS,
167
+ *DISTRIBUTION_VALIDATORS,
168
+ *STRING_VALIDATORS,
169
+ *DATETIME_VALIDATORS,
170
+ *AGGREGATE_VALIDATORS,
171
+ *CROSS_TABLE_VALIDATORS,
172
+ *MULTI_COLUMN_VALIDATORS,
173
+ *QUERY_VALIDATORS,
174
+ *TABLE_VALIDATORS,
175
+ *GEOSPATIAL_VALIDATORS,
176
+ *DRIFT_VALIDATORS,
177
+ *ANOMALY_VALIDATORS,
178
+ *PRIVACY_VALIDATORS,
179
+ ]
180
+
181
+
182
+ # Complete validator registry
183
+ VALIDATOR_REGISTRY: list[ValidatorDefinition] = _build_registry()
184
+
185
+
186
+ def _update_category_counts() -> None:
187
+ """Update validator counts in category info."""
188
+ category_counts: dict[str, int] = {}
189
+ for validator in VALIDATOR_REGISTRY:
190
+ cat = validator.category.value
191
+ category_counts[cat] = category_counts.get(cat, 0) + 1
192
+
193
+ for cat_info in CATEGORY_INFO:
194
+ cat_info.validator_count = category_counts.get(cat_info.value, 0)
195
+
196
+
197
+ # Update counts on module load
198
+ _update_category_counts()
199
+
200
+
201
+ def get_validator_by_name(name: str) -> ValidatorDefinition | None:
202
+ """Get a validator definition by name.
203
+
204
+ Args:
205
+ name: Validator name (case-insensitive).
206
+
207
+ Returns:
208
+ ValidatorDefinition if found, None otherwise.
209
+ """
210
+ name_lower = name.lower()
211
+ for validator in VALIDATOR_REGISTRY:
212
+ if validator.name.lower() == name_lower:
213
+ return validator
214
+ return None
215
+
216
+
217
+ def get_validators_by_category(
218
+ category: ValidatorCategory | str,
219
+ ) -> list[ValidatorDefinition]:
220
+ """Get all validators in a category.
221
+
222
+ Args:
223
+ category: Validator category (enum or string value).
224
+
225
+ Returns:
226
+ List of validator definitions.
227
+ """
228
+ if isinstance(category, str):
229
+ category_value = category
230
+ else:
231
+ category_value = category.value
232
+
233
+ return [v for v in VALIDATOR_REGISTRY if v.category.value == category_value]
234
+
235
+
236
+ def search_validators(
237
+ query: str,
238
+ category: ValidatorCategory | str | None = None,
239
+ include_experimental: bool = False,
240
+ include_deprecated: bool = False,
241
+ ) -> list[ValidatorDefinition]:
242
+ """Search validators by name, description, or tags.
243
+
244
+ Args:
245
+ query: Search query string.
246
+ category: Optional category filter.
247
+ include_experimental: Include experimental validators.
248
+ include_deprecated: Include deprecated validators.
249
+
250
+ Returns:
251
+ List of matching validator definitions.
252
+ """
253
+ query_lower = query.lower()
254
+ results = []
255
+
256
+ for validator in VALIDATOR_REGISTRY:
257
+ # Apply filters
258
+ if not include_experimental and validator.experimental:
259
+ continue
260
+ if not include_deprecated and validator.deprecated:
261
+ continue
262
+ if category:
263
+ cat_value = category if isinstance(category, str) else category.value
264
+ if validator.category.value != cat_value:
265
+ continue
266
+
267
+ # Search in name, display_name, description, and tags
268
+ if (
269
+ query_lower in validator.name.lower()
270
+ or query_lower in validator.display_name.lower()
271
+ or query_lower in validator.description.lower()
272
+ or any(query_lower in tag for tag in validator.tags)
273
+ ):
274
+ results.append(validator)
275
+
276
+ return results
277
+
278
+
279
+ def get_category_info(category: ValidatorCategory | str) -> CategoryInfo | None:
280
+ """Get category metadata.
281
+
282
+ Args:
283
+ category: Category enum or string value.
284
+
285
+ Returns:
286
+ CategoryInfo if found, None otherwise.
287
+ """
288
+ cat_value = category if isinstance(category, str) else category.value
289
+ for info in CATEGORY_INFO:
290
+ if info.value == cat_value:
291
+ return info
292
+ return None
293
+
294
+
295
+ def get_validators_requiring_extra(extra: Literal["drift", "anomaly"]) -> list[ValidatorDefinition]:
296
+ """Get validators that require an optional dependency.
297
+
298
+ Args:
299
+ extra: Required extra package ('drift' or 'anomaly').
300
+
301
+ Returns:
302
+ List of validators requiring the specified extra.
303
+ """
304
+ return [v for v in VALIDATOR_REGISTRY if v.requires_extra == extra]
305
+
306
+
307
+ def get_validator_stats() -> dict[str, int]:
308
+ """Get statistics about the validator registry.
309
+
310
+ Returns:
311
+ Dict with category names as keys and validator counts as values.
312
+ """
313
+ stats: dict[str, int] = {}
314
+ for validator in VALIDATOR_REGISTRY:
315
+ cat = validator.category.value
316
+ stats[cat] = stats.get(cat, 0) + 1
317
+ stats["total"] = len(VALIDATOR_REGISTRY)
318
+ return stats