truthound-dashboard 1.3.1__py3-none-any.whl → 1.4.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 (169) hide show
  1. truthound_dashboard/api/alerts.py +258 -0
  2. truthound_dashboard/api/anomaly.py +1302 -0
  3. truthound_dashboard/api/cross_alerts.py +352 -0
  4. truthound_dashboard/api/deps.py +143 -0
  5. truthound_dashboard/api/drift_monitor.py +540 -0
  6. truthound_dashboard/api/lineage.py +1151 -0
  7. truthound_dashboard/api/maintenance.py +363 -0
  8. truthound_dashboard/api/middleware.py +373 -1
  9. truthound_dashboard/api/model_monitoring.py +805 -0
  10. truthound_dashboard/api/notifications_advanced.py +2452 -0
  11. truthound_dashboard/api/plugins.py +2096 -0
  12. truthound_dashboard/api/profile.py +211 -14
  13. truthound_dashboard/api/reports.py +853 -0
  14. truthound_dashboard/api/router.py +147 -0
  15. truthound_dashboard/api/rule_suggestions.py +310 -0
  16. truthound_dashboard/api/schema_evolution.py +231 -0
  17. truthound_dashboard/api/sources.py +47 -3
  18. truthound_dashboard/api/triggers.py +190 -0
  19. truthound_dashboard/api/validations.py +13 -0
  20. truthound_dashboard/api/validators.py +333 -4
  21. truthound_dashboard/api/versioning.py +309 -0
  22. truthound_dashboard/api/websocket.py +301 -0
  23. truthound_dashboard/core/__init__.py +27 -0
  24. truthound_dashboard/core/anomaly.py +1395 -0
  25. truthound_dashboard/core/anomaly_explainer.py +633 -0
  26. truthound_dashboard/core/cache.py +206 -0
  27. truthound_dashboard/core/cached_services.py +422 -0
  28. truthound_dashboard/core/charts.py +352 -0
  29. truthound_dashboard/core/connections.py +1069 -42
  30. truthound_dashboard/core/cross_alerts.py +837 -0
  31. truthound_dashboard/core/drift_monitor.py +1477 -0
  32. truthound_dashboard/core/drift_sampling.py +669 -0
  33. truthound_dashboard/core/i18n/__init__.py +42 -0
  34. truthound_dashboard/core/i18n/detector.py +173 -0
  35. truthound_dashboard/core/i18n/messages.py +564 -0
  36. truthound_dashboard/core/lineage.py +971 -0
  37. truthound_dashboard/core/maintenance.py +443 -5
  38. truthound_dashboard/core/model_monitoring.py +1043 -0
  39. truthound_dashboard/core/notifications/channels.py +1020 -1
  40. truthound_dashboard/core/notifications/deduplication/__init__.py +143 -0
  41. truthound_dashboard/core/notifications/deduplication/policies.py +274 -0
  42. truthound_dashboard/core/notifications/deduplication/service.py +400 -0
  43. truthound_dashboard/core/notifications/deduplication/stores.py +2365 -0
  44. truthound_dashboard/core/notifications/deduplication/strategies.py +422 -0
  45. truthound_dashboard/core/notifications/dispatcher.py +43 -0
  46. truthound_dashboard/core/notifications/escalation/__init__.py +149 -0
  47. truthound_dashboard/core/notifications/escalation/backends.py +1384 -0
  48. truthound_dashboard/core/notifications/escalation/engine.py +429 -0
  49. truthound_dashboard/core/notifications/escalation/models.py +336 -0
  50. truthound_dashboard/core/notifications/escalation/scheduler.py +1187 -0
  51. truthound_dashboard/core/notifications/escalation/state_machine.py +330 -0
  52. truthound_dashboard/core/notifications/escalation/stores.py +2896 -0
  53. truthound_dashboard/core/notifications/events.py +49 -0
  54. truthound_dashboard/core/notifications/metrics/__init__.py +115 -0
  55. truthound_dashboard/core/notifications/metrics/base.py +528 -0
  56. truthound_dashboard/core/notifications/metrics/collectors.py +583 -0
  57. truthound_dashboard/core/notifications/routing/__init__.py +169 -0
  58. truthound_dashboard/core/notifications/routing/combinators.py +184 -0
  59. truthound_dashboard/core/notifications/routing/config.py +375 -0
  60. truthound_dashboard/core/notifications/routing/config_parser.py +867 -0
  61. truthound_dashboard/core/notifications/routing/engine.py +382 -0
  62. truthound_dashboard/core/notifications/routing/expression_engine.py +1269 -0
  63. truthound_dashboard/core/notifications/routing/jinja2_engine.py +774 -0
  64. truthound_dashboard/core/notifications/routing/rules.py +625 -0
  65. truthound_dashboard/core/notifications/routing/validator.py +678 -0
  66. truthound_dashboard/core/notifications/service.py +2 -0
  67. truthound_dashboard/core/notifications/stats_aggregator.py +850 -0
  68. truthound_dashboard/core/notifications/throttling/__init__.py +83 -0
  69. truthound_dashboard/core/notifications/throttling/builder.py +311 -0
  70. truthound_dashboard/core/notifications/throttling/stores.py +1859 -0
  71. truthound_dashboard/core/notifications/throttling/throttlers.py +633 -0
  72. truthound_dashboard/core/openlineage.py +1028 -0
  73. truthound_dashboard/core/plugins/__init__.py +39 -0
  74. truthound_dashboard/core/plugins/docs/__init__.py +39 -0
  75. truthound_dashboard/core/plugins/docs/extractor.py +703 -0
  76. truthound_dashboard/core/plugins/docs/renderers.py +804 -0
  77. truthound_dashboard/core/plugins/hooks/__init__.py +63 -0
  78. truthound_dashboard/core/plugins/hooks/decorators.py +367 -0
  79. truthound_dashboard/core/plugins/hooks/manager.py +403 -0
  80. truthound_dashboard/core/plugins/hooks/protocols.py +265 -0
  81. truthound_dashboard/core/plugins/lifecycle/__init__.py +41 -0
  82. truthound_dashboard/core/plugins/lifecycle/hot_reload.py +584 -0
  83. truthound_dashboard/core/plugins/lifecycle/machine.py +419 -0
  84. truthound_dashboard/core/plugins/lifecycle/states.py +266 -0
  85. truthound_dashboard/core/plugins/loader.py +504 -0
  86. truthound_dashboard/core/plugins/registry.py +810 -0
  87. truthound_dashboard/core/plugins/reporter_executor.py +588 -0
  88. truthound_dashboard/core/plugins/sandbox/__init__.py +59 -0
  89. truthound_dashboard/core/plugins/sandbox/code_validator.py +243 -0
  90. truthound_dashboard/core/plugins/sandbox/engines.py +770 -0
  91. truthound_dashboard/core/plugins/sandbox/protocols.py +194 -0
  92. truthound_dashboard/core/plugins/sandbox.py +617 -0
  93. truthound_dashboard/core/plugins/security/__init__.py +68 -0
  94. truthound_dashboard/core/plugins/security/analyzer.py +535 -0
  95. truthound_dashboard/core/plugins/security/policies.py +311 -0
  96. truthound_dashboard/core/plugins/security/protocols.py +296 -0
  97. truthound_dashboard/core/plugins/security/signing.py +842 -0
  98. truthound_dashboard/core/plugins/security.py +446 -0
  99. truthound_dashboard/core/plugins/validator_executor.py +401 -0
  100. truthound_dashboard/core/plugins/versioning/__init__.py +51 -0
  101. truthound_dashboard/core/plugins/versioning/constraints.py +377 -0
  102. truthound_dashboard/core/plugins/versioning/dependencies.py +541 -0
  103. truthound_dashboard/core/plugins/versioning/semver.py +266 -0
  104. truthound_dashboard/core/profile_comparison.py +601 -0
  105. truthound_dashboard/core/report_history.py +570 -0
  106. truthound_dashboard/core/reporters/__init__.py +57 -0
  107. truthound_dashboard/core/reporters/base.py +296 -0
  108. truthound_dashboard/core/reporters/csv_reporter.py +155 -0
  109. truthound_dashboard/core/reporters/html_reporter.py +598 -0
  110. truthound_dashboard/core/reporters/i18n/__init__.py +65 -0
  111. truthound_dashboard/core/reporters/i18n/base.py +494 -0
  112. truthound_dashboard/core/reporters/i18n/catalogs.py +930 -0
  113. truthound_dashboard/core/reporters/json_reporter.py +160 -0
  114. truthound_dashboard/core/reporters/junit_reporter.py +233 -0
  115. truthound_dashboard/core/reporters/markdown_reporter.py +207 -0
  116. truthound_dashboard/core/reporters/pdf_reporter.py +209 -0
  117. truthound_dashboard/core/reporters/registry.py +272 -0
  118. truthound_dashboard/core/rule_generator.py +2088 -0
  119. truthound_dashboard/core/scheduler.py +822 -12
  120. truthound_dashboard/core/schema_evolution.py +858 -0
  121. truthound_dashboard/core/services.py +152 -9
  122. truthound_dashboard/core/statistics.py +718 -0
  123. truthound_dashboard/core/streaming_anomaly.py +883 -0
  124. truthound_dashboard/core/triggers/__init__.py +45 -0
  125. truthound_dashboard/core/triggers/base.py +226 -0
  126. truthound_dashboard/core/triggers/evaluators.py +609 -0
  127. truthound_dashboard/core/triggers/factory.py +363 -0
  128. truthound_dashboard/core/unified_alerts.py +870 -0
  129. truthound_dashboard/core/validation_limits.py +509 -0
  130. truthound_dashboard/core/versioning.py +709 -0
  131. truthound_dashboard/core/websocket/__init__.py +59 -0
  132. truthound_dashboard/core/websocket/manager.py +512 -0
  133. truthound_dashboard/core/websocket/messages.py +130 -0
  134. truthound_dashboard/db/__init__.py +30 -0
  135. truthound_dashboard/db/models.py +3375 -3
  136. truthound_dashboard/main.py +22 -0
  137. truthound_dashboard/schemas/__init__.py +396 -1
  138. truthound_dashboard/schemas/anomaly.py +1258 -0
  139. truthound_dashboard/schemas/base.py +4 -0
  140. truthound_dashboard/schemas/cross_alerts.py +334 -0
  141. truthound_dashboard/schemas/drift_monitor.py +890 -0
  142. truthound_dashboard/schemas/lineage.py +428 -0
  143. truthound_dashboard/schemas/maintenance.py +154 -0
  144. truthound_dashboard/schemas/model_monitoring.py +374 -0
  145. truthound_dashboard/schemas/notifications_advanced.py +1363 -0
  146. truthound_dashboard/schemas/openlineage.py +704 -0
  147. truthound_dashboard/schemas/plugins.py +1293 -0
  148. truthound_dashboard/schemas/profile.py +420 -34
  149. truthound_dashboard/schemas/profile_comparison.py +242 -0
  150. truthound_dashboard/schemas/reports.py +285 -0
  151. truthound_dashboard/schemas/rule_suggestion.py +434 -0
  152. truthound_dashboard/schemas/schema_evolution.py +164 -0
  153. truthound_dashboard/schemas/source.py +117 -2
  154. truthound_dashboard/schemas/triggers.py +511 -0
  155. truthound_dashboard/schemas/unified_alerts.py +223 -0
  156. truthound_dashboard/schemas/validation.py +25 -1
  157. truthound_dashboard/schemas/validators/__init__.py +11 -0
  158. truthound_dashboard/schemas/validators/base.py +151 -0
  159. truthound_dashboard/schemas/versioning.py +152 -0
  160. truthound_dashboard/static/index.html +2 -2
  161. {truthound_dashboard-1.3.1.dist-info → truthound_dashboard-1.4.0.dist-info}/METADATA +142 -22
  162. truthound_dashboard-1.4.0.dist-info/RECORD +239 -0
  163. truthound_dashboard/static/assets/index-BZG20KuF.js +0 -586
  164. truthound_dashboard/static/assets/index-D_HyZ3pb.css +0 -1
  165. truthound_dashboard/static/assets/unmerged_dictionaries-CtpqQBm0.js +0 -1
  166. truthound_dashboard-1.3.1.dist-info/RECORD +0 -110
  167. {truthound_dashboard-1.3.1.dist-info → truthound_dashboard-1.4.0.dist-info}/WHEEL +0 -0
  168. {truthound_dashboard-1.3.1.dist-info → truthound_dashboard-1.4.0.dist-info}/entry_points.txt +0 -0
  169. {truthound_dashboard-1.3.1.dist-info → truthound_dashboard-1.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -60,6 +60,10 @@ class ResponseWrapper(BaseSchema, Generic[T]):
60
60
  message: str | None = Field(default=None, description="Optional message")
61
61
 
62
62
 
63
+ # Alias for backward compatibility with newer code
64
+ DataResponse = ResponseWrapper
65
+
66
+
63
67
  class ListResponseWrapper(BaseSchema, Generic[T]):
64
68
  """Generic wrapper for list responses with pagination.
65
69
 
@@ -0,0 +1,334 @@
1
+ """Cross-alert correlation schemas.
2
+
3
+ This module defines schemas for cross-feature integration between
4
+ Anomaly Detection and Drift Monitoring alerts.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from datetime import datetime
10
+ from typing import Literal
11
+
12
+ from pydantic import Field
13
+
14
+ from .base import BaseSchema, IDMixin, TimestampMixin, ListResponseWrapper
15
+
16
+
17
+ # =============================================================================
18
+ # Enums and Types
19
+ # =============================================================================
20
+
21
+ AlertType = Literal["anomaly", "drift"]
22
+ CorrelationStrength = Literal["strong", "moderate", "weak", "none"]
23
+ TriggerDirection = Literal["anomaly_to_drift", "drift_to_anomaly", "bidirectional"]
24
+
25
+
26
+ # =============================================================================
27
+ # Cross-Alert Correlation Schemas
28
+ # =============================================================================
29
+
30
+
31
+ class CorrelatedAlert(BaseSchema):
32
+ """A single alert that is part of a correlation."""
33
+
34
+ alert_id: str = Field(..., description="Alert ID")
35
+ alert_type: AlertType = Field(..., description="Type of alert (anomaly or drift)")
36
+ source_id: str = Field(..., description="Related source ID")
37
+ source_name: str | None = Field(default=None, description="Source name for display")
38
+ severity: str = Field(..., description="Alert severity level")
39
+ message: str = Field(..., description="Alert message")
40
+ created_at: datetime = Field(..., description="When the alert was created")
41
+
42
+ # Type-specific fields
43
+ anomaly_rate: float | None = Field(
44
+ default=None,
45
+ description="Anomaly rate (for anomaly alerts)",
46
+ )
47
+ anomaly_count: int | None = Field(
48
+ default=None,
49
+ description="Number of anomalies (for anomaly alerts)",
50
+ )
51
+ drift_percentage: float | None = Field(
52
+ default=None,
53
+ description="Drift percentage (for drift alerts)",
54
+ )
55
+ drifted_columns: list[str] | None = Field(
56
+ default=None,
57
+ description="Drifted columns (for drift alerts)",
58
+ )
59
+
60
+
61
+ class CrossAlertCorrelation(IDMixin, TimestampMixin, BaseSchema):
62
+ """A correlation between anomaly and drift alerts."""
63
+
64
+ source_id: str = Field(..., description="Primary source ID")
65
+ source_name: str | None = Field(default=None, description="Source name")
66
+
67
+ # Correlation details
68
+ correlation_strength: CorrelationStrength = Field(
69
+ default="moderate",
70
+ description="Strength of the correlation",
71
+ )
72
+ confidence_score: float = Field(
73
+ default=0.0,
74
+ ge=0.0,
75
+ le=1.0,
76
+ description="Confidence score of the correlation (0-1)",
77
+ )
78
+ time_delta_seconds: int = Field(
79
+ default=0,
80
+ description="Time difference between alerts in seconds",
81
+ )
82
+
83
+ # Related alerts
84
+ anomaly_alert: CorrelatedAlert | None = Field(
85
+ default=None,
86
+ description="The anomaly alert in this correlation",
87
+ )
88
+ drift_alert: CorrelatedAlert | None = Field(
89
+ default=None,
90
+ description="The drift alert in this correlation",
91
+ )
92
+
93
+ # Analysis
94
+ common_columns: list[str] = Field(
95
+ default_factory=list,
96
+ description="Columns affected by both anomaly and drift",
97
+ )
98
+ suggested_action: str | None = Field(
99
+ default=None,
100
+ description="Suggested remediation action",
101
+ )
102
+ notes: str | None = Field(
103
+ default=None,
104
+ description="Additional notes about the correlation",
105
+ )
106
+
107
+
108
+ class CrossAlertCorrelationListResponse(ListResponseWrapper[CrossAlertCorrelation]):
109
+ """Paginated list of cross-alert correlations."""
110
+
111
+ pass
112
+
113
+
114
+ # =============================================================================
115
+ # Auto-Trigger Configuration Schemas
116
+ # =============================================================================
117
+
118
+
119
+ class AutoTriggerThresholds(BaseSchema):
120
+ """Thresholds for auto-triggering checks."""
121
+
122
+ # Anomaly thresholds
123
+ anomaly_rate_threshold: float = Field(
124
+ default=0.1,
125
+ ge=0.0,
126
+ le=1.0,
127
+ description="Minimum anomaly rate to trigger drift check",
128
+ )
129
+ anomaly_count_threshold: int = Field(
130
+ default=10,
131
+ ge=1,
132
+ description="Minimum anomaly count to trigger drift check",
133
+ )
134
+
135
+ # Drift thresholds
136
+ drift_percentage_threshold: float = Field(
137
+ default=10.0,
138
+ ge=0.0,
139
+ le=100.0,
140
+ description="Minimum drift percentage to trigger anomaly check",
141
+ )
142
+ drift_columns_threshold: int = Field(
143
+ default=2,
144
+ ge=1,
145
+ description="Minimum drifted columns to trigger anomaly check",
146
+ )
147
+
148
+
149
+ class AutoTriggerConfig(IDMixin, TimestampMixin, BaseSchema):
150
+ """Configuration for auto-triggering cross-feature checks."""
151
+
152
+ source_id: str | None = Field(
153
+ default=None,
154
+ description="Source ID (None for global config)",
155
+ )
156
+
157
+ # Enable/disable flags
158
+ enabled: bool = Field(
159
+ default=True,
160
+ description="Whether auto-triggering is enabled",
161
+ )
162
+ trigger_drift_on_anomaly: bool = Field(
163
+ default=True,
164
+ description="Trigger drift check when anomaly detected",
165
+ )
166
+ trigger_anomaly_on_drift: bool = Field(
167
+ default=True,
168
+ description="Trigger anomaly check when drift detected",
169
+ )
170
+
171
+ # Thresholds
172
+ thresholds: AutoTriggerThresholds = Field(
173
+ default_factory=AutoTriggerThresholds,
174
+ description="Trigger thresholds",
175
+ )
176
+
177
+ # Notification preferences
178
+ notify_on_correlation: bool = Field(
179
+ default=True,
180
+ description="Send notification when correlation detected",
181
+ )
182
+ notification_channel_ids: list[str] | None = Field(
183
+ default=None,
184
+ description="Notification channel IDs",
185
+ )
186
+
187
+ # Cooldown to prevent alert storms
188
+ cooldown_seconds: int = Field(
189
+ default=300,
190
+ ge=0,
191
+ description="Minimum time between auto-triggered checks (seconds)",
192
+ )
193
+ last_anomaly_trigger_at: datetime | None = Field(
194
+ default=None,
195
+ description="Last time anomaly check was auto-triggered",
196
+ )
197
+ last_drift_trigger_at: datetime | None = Field(
198
+ default=None,
199
+ description="Last time drift check was auto-triggered",
200
+ )
201
+
202
+
203
+ class AutoTriggerConfigCreate(BaseSchema):
204
+ """Schema for creating auto-trigger configuration."""
205
+
206
+ source_id: str | None = Field(default=None)
207
+ enabled: bool = Field(default=True)
208
+ trigger_drift_on_anomaly: bool = Field(default=True)
209
+ trigger_anomaly_on_drift: bool = Field(default=True)
210
+ thresholds: AutoTriggerThresholds | None = Field(default=None)
211
+ notify_on_correlation: bool = Field(default=True)
212
+ notification_channel_ids: list[str] | None = Field(default=None)
213
+ cooldown_seconds: int = Field(default=300, ge=0)
214
+
215
+
216
+ class AutoTriggerConfigUpdate(BaseSchema):
217
+ """Schema for updating auto-trigger configuration."""
218
+
219
+ enabled: bool | None = Field(default=None)
220
+ trigger_drift_on_anomaly: bool | None = Field(default=None)
221
+ trigger_anomaly_on_drift: bool | None = Field(default=None)
222
+ thresholds: AutoTriggerThresholds | None = Field(default=None)
223
+ notify_on_correlation: bool | None = Field(default=None)
224
+ notification_channel_ids: list[str] | None = Field(default=None)
225
+ cooldown_seconds: int | None = Field(default=None, ge=0)
226
+
227
+
228
+ # =============================================================================
229
+ # Auto-Trigger Event Schemas
230
+ # =============================================================================
231
+
232
+
233
+ class AutoTriggerEvent(IDMixin, TimestampMixin, BaseSchema):
234
+ """Record of an auto-triggered check."""
235
+
236
+ source_id: str = Field(..., description="Source ID")
237
+ trigger_type: TriggerDirection = Field(
238
+ ...,
239
+ description="Direction of the trigger",
240
+ )
241
+
242
+ # Trigger source
243
+ trigger_alert_id: str = Field(..., description="ID of the alert that triggered this")
244
+ trigger_alert_type: AlertType = Field(..., description="Type of triggering alert")
245
+
246
+ # Result
247
+ result_id: str | None = Field(
248
+ default=None,
249
+ description="ID of the resulting detection/comparison",
250
+ )
251
+ correlation_found: bool = Field(
252
+ default=False,
253
+ description="Whether a correlation was found",
254
+ )
255
+ correlation_id: str | None = Field(
256
+ default=None,
257
+ description="ID of the correlation if found",
258
+ )
259
+
260
+ # Status
261
+ status: Literal["pending", "running", "completed", "failed", "skipped"] = Field(
262
+ default="pending",
263
+ description="Status of the auto-triggered check",
264
+ )
265
+ error_message: str | None = Field(
266
+ default=None,
267
+ description="Error message if failed",
268
+ )
269
+ skipped_reason: str | None = Field(
270
+ default=None,
271
+ description="Reason if skipped (e.g., cooldown)",
272
+ )
273
+
274
+
275
+ class AutoTriggerEventListResponse(ListResponseWrapper[AutoTriggerEvent]):
276
+ """Paginated list of auto-trigger events."""
277
+
278
+ pass
279
+
280
+
281
+ # =============================================================================
282
+ # Summary Schemas
283
+ # =============================================================================
284
+
285
+
286
+ class CrossAlertSummary(BaseSchema):
287
+ """Summary of cross-alert correlations."""
288
+
289
+ total_correlations: int = Field(
290
+ default=0,
291
+ description="Total number of correlations",
292
+ )
293
+ strong_correlations: int = Field(
294
+ default=0,
295
+ description="Number of strong correlations",
296
+ )
297
+ moderate_correlations: int = Field(
298
+ default=0,
299
+ description="Number of moderate correlations",
300
+ )
301
+ weak_correlations: int = Field(
302
+ default=0,
303
+ description="Number of weak correlations",
304
+ )
305
+
306
+ # Recent activity
307
+ recent_correlations_24h: int = Field(
308
+ default=0,
309
+ description="Correlations in the last 24 hours",
310
+ )
311
+ recent_auto_triggers_24h: int = Field(
312
+ default=0,
313
+ description="Auto-triggers in the last 24 hours",
314
+ )
315
+
316
+ # Top affected sources
317
+ top_affected_sources: list[dict] = Field(
318
+ default_factory=list,
319
+ description="Sources with most correlations",
320
+ )
321
+
322
+ # Auto-trigger stats
323
+ auto_trigger_enabled: bool = Field(
324
+ default=True,
325
+ description="Whether auto-triggering is enabled globally",
326
+ )
327
+ anomaly_to_drift_triggers: int = Field(
328
+ default=0,
329
+ description="Count of anomaly-to-drift triggers",
330
+ )
331
+ drift_to_anomaly_triggers: int = Field(
332
+ default=0,
333
+ description="Count of drift-to-anomaly triggers",
334
+ )