truthound-dashboard 1.4.4__py3-none-any.whl → 1.5.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 (205) hide show
  1. truthound_dashboard/api/alerts.py +75 -86
  2. truthound_dashboard/api/anomaly.py +7 -13
  3. truthound_dashboard/api/cross_alerts.py +38 -52
  4. truthound_dashboard/api/drift.py +49 -59
  5. truthound_dashboard/api/drift_monitor.py +234 -79
  6. truthound_dashboard/api/enterprise_sampling.py +498 -0
  7. truthound_dashboard/api/history.py +57 -5
  8. truthound_dashboard/api/lineage.py +3 -48
  9. truthound_dashboard/api/maintenance.py +104 -49
  10. truthound_dashboard/api/mask.py +1 -2
  11. truthound_dashboard/api/middleware.py +2 -1
  12. truthound_dashboard/api/model_monitoring.py +435 -311
  13. truthound_dashboard/api/notifications.py +227 -191
  14. truthound_dashboard/api/notifications_advanced.py +21 -20
  15. truthound_dashboard/api/observability.py +586 -0
  16. truthound_dashboard/api/plugins.py +2 -433
  17. truthound_dashboard/api/profile.py +199 -37
  18. truthound_dashboard/api/quality_reporter.py +701 -0
  19. truthound_dashboard/api/reports.py +7 -16
  20. truthound_dashboard/api/router.py +66 -0
  21. truthound_dashboard/api/rule_suggestions.py +5 -5
  22. truthound_dashboard/api/scan.py +17 -19
  23. truthound_dashboard/api/schedules.py +85 -50
  24. truthound_dashboard/api/schema_evolution.py +6 -6
  25. truthound_dashboard/api/schema_watcher.py +667 -0
  26. truthound_dashboard/api/sources.py +98 -27
  27. truthound_dashboard/api/tiering.py +1323 -0
  28. truthound_dashboard/api/triggers.py +14 -11
  29. truthound_dashboard/api/validations.py +12 -11
  30. truthound_dashboard/api/versioning.py +1 -6
  31. truthound_dashboard/core/__init__.py +129 -3
  32. truthound_dashboard/core/actions/__init__.py +62 -0
  33. truthound_dashboard/core/actions/custom.py +426 -0
  34. truthound_dashboard/core/actions/notifications.py +910 -0
  35. truthound_dashboard/core/actions/storage.py +472 -0
  36. truthound_dashboard/core/actions/webhook.py +281 -0
  37. truthound_dashboard/core/anomaly.py +262 -67
  38. truthound_dashboard/core/anomaly_explainer.py +4 -3
  39. truthound_dashboard/core/backends/__init__.py +67 -0
  40. truthound_dashboard/core/backends/base.py +299 -0
  41. truthound_dashboard/core/backends/errors.py +191 -0
  42. truthound_dashboard/core/backends/factory.py +423 -0
  43. truthound_dashboard/core/backends/mock_backend.py +451 -0
  44. truthound_dashboard/core/backends/truthound_backend.py +718 -0
  45. truthound_dashboard/core/checkpoint/__init__.py +87 -0
  46. truthound_dashboard/core/checkpoint/adapters.py +814 -0
  47. truthound_dashboard/core/checkpoint/checkpoint.py +491 -0
  48. truthound_dashboard/core/checkpoint/runner.py +270 -0
  49. truthound_dashboard/core/connections.py +437 -10
  50. truthound_dashboard/core/converters/__init__.py +14 -0
  51. truthound_dashboard/core/converters/truthound.py +620 -0
  52. truthound_dashboard/core/cross_alerts.py +540 -320
  53. truthound_dashboard/core/datasource_factory.py +1672 -0
  54. truthound_dashboard/core/drift_monitor.py +216 -20
  55. truthound_dashboard/core/enterprise_sampling.py +1291 -0
  56. truthound_dashboard/core/interfaces/__init__.py +225 -0
  57. truthound_dashboard/core/interfaces/actions.py +652 -0
  58. truthound_dashboard/core/interfaces/base.py +247 -0
  59. truthound_dashboard/core/interfaces/checkpoint.py +676 -0
  60. truthound_dashboard/core/interfaces/protocols.py +664 -0
  61. truthound_dashboard/core/interfaces/reporters.py +650 -0
  62. truthound_dashboard/core/interfaces/routing.py +646 -0
  63. truthound_dashboard/core/interfaces/triggers.py +619 -0
  64. truthound_dashboard/core/lineage.py +407 -71
  65. truthound_dashboard/core/model_monitoring.py +431 -3
  66. truthound_dashboard/core/notifications/base.py +4 -0
  67. truthound_dashboard/core/notifications/channels.py +501 -1203
  68. truthound_dashboard/core/notifications/deduplication/__init__.py +81 -115
  69. truthound_dashboard/core/notifications/deduplication/service.py +131 -348
  70. truthound_dashboard/core/notifications/dispatcher.py +202 -11
  71. truthound_dashboard/core/notifications/escalation/__init__.py +119 -106
  72. truthound_dashboard/core/notifications/escalation/engine.py +168 -358
  73. truthound_dashboard/core/notifications/routing/__init__.py +88 -128
  74. truthound_dashboard/core/notifications/routing/engine.py +90 -317
  75. truthound_dashboard/core/notifications/stats_aggregator.py +246 -1
  76. truthound_dashboard/core/notifications/throttling/__init__.py +67 -50
  77. truthound_dashboard/core/notifications/throttling/builder.py +117 -255
  78. truthound_dashboard/core/notifications/truthound_adapter.py +842 -0
  79. truthound_dashboard/core/phase5/collaboration.py +1 -1
  80. truthound_dashboard/core/plugins/lifecycle/__init__.py +0 -13
  81. truthound_dashboard/core/quality_reporter.py +1359 -0
  82. truthound_dashboard/core/report_history.py +0 -6
  83. truthound_dashboard/core/reporters/__init__.py +175 -14
  84. truthound_dashboard/core/reporters/adapters.py +943 -0
  85. truthound_dashboard/core/reporters/base.py +0 -3
  86. truthound_dashboard/core/reporters/builtin/__init__.py +18 -0
  87. truthound_dashboard/core/reporters/builtin/csv_reporter.py +111 -0
  88. truthound_dashboard/core/reporters/builtin/html_reporter.py +270 -0
  89. truthound_dashboard/core/reporters/builtin/json_reporter.py +127 -0
  90. truthound_dashboard/core/reporters/compat.py +266 -0
  91. truthound_dashboard/core/reporters/csv_reporter.py +2 -35
  92. truthound_dashboard/core/reporters/factory.py +526 -0
  93. truthound_dashboard/core/reporters/interfaces.py +745 -0
  94. truthound_dashboard/core/reporters/registry.py +1 -10
  95. truthound_dashboard/core/scheduler.py +165 -0
  96. truthound_dashboard/core/schema_evolution.py +3 -3
  97. truthound_dashboard/core/schema_watcher.py +1528 -0
  98. truthound_dashboard/core/services.py +595 -76
  99. truthound_dashboard/core/store_manager.py +810 -0
  100. truthound_dashboard/core/streaming_anomaly.py +169 -4
  101. truthound_dashboard/core/tiering.py +1309 -0
  102. truthound_dashboard/core/triggers/evaluators.py +178 -8
  103. truthound_dashboard/core/truthound_adapter.py +2620 -197
  104. truthound_dashboard/core/unified_alerts.py +23 -20
  105. truthound_dashboard/db/__init__.py +8 -0
  106. truthound_dashboard/db/database.py +8 -2
  107. truthound_dashboard/db/models.py +944 -25
  108. truthound_dashboard/db/repository.py +2 -0
  109. truthound_dashboard/main.py +11 -0
  110. truthound_dashboard/schemas/__init__.py +177 -16
  111. truthound_dashboard/schemas/base.py +44 -23
  112. truthound_dashboard/schemas/collaboration.py +19 -6
  113. truthound_dashboard/schemas/cross_alerts.py +19 -3
  114. truthound_dashboard/schemas/drift.py +61 -55
  115. truthound_dashboard/schemas/drift_monitor.py +67 -23
  116. truthound_dashboard/schemas/enterprise_sampling.py +653 -0
  117. truthound_dashboard/schemas/lineage.py +0 -33
  118. truthound_dashboard/schemas/mask.py +10 -8
  119. truthound_dashboard/schemas/model_monitoring.py +89 -10
  120. truthound_dashboard/schemas/notifications_advanced.py +13 -0
  121. truthound_dashboard/schemas/observability.py +453 -0
  122. truthound_dashboard/schemas/plugins.py +0 -280
  123. truthound_dashboard/schemas/profile.py +154 -247
  124. truthound_dashboard/schemas/quality_reporter.py +403 -0
  125. truthound_dashboard/schemas/reports.py +2 -2
  126. truthound_dashboard/schemas/rule_suggestion.py +8 -1
  127. truthound_dashboard/schemas/scan.py +4 -24
  128. truthound_dashboard/schemas/schedule.py +11 -3
  129. truthound_dashboard/schemas/schema_watcher.py +727 -0
  130. truthound_dashboard/schemas/source.py +17 -2
  131. truthound_dashboard/schemas/tiering.py +822 -0
  132. truthound_dashboard/schemas/triggers.py +16 -0
  133. truthound_dashboard/schemas/unified_alerts.py +7 -0
  134. truthound_dashboard/schemas/validation.py +0 -13
  135. truthound_dashboard/schemas/validators/base.py +41 -21
  136. truthound_dashboard/schemas/validators/business_rule_validators.py +244 -0
  137. truthound_dashboard/schemas/validators/localization_validators.py +273 -0
  138. truthound_dashboard/schemas/validators/ml_feature_validators.py +308 -0
  139. truthound_dashboard/schemas/validators/profiling_validators.py +275 -0
  140. truthound_dashboard/schemas/validators/referential_validators.py +312 -0
  141. truthound_dashboard/schemas/validators/registry.py +93 -8
  142. truthound_dashboard/schemas/validators/timeseries_validators.py +389 -0
  143. truthound_dashboard/schemas/versioning.py +1 -6
  144. truthound_dashboard/static/index.html +2 -2
  145. truthound_dashboard-1.5.0.dist-info/METADATA +309 -0
  146. {truthound_dashboard-1.4.4.dist-info → truthound_dashboard-1.5.0.dist-info}/RECORD +149 -148
  147. truthound_dashboard/core/plugins/hooks/__init__.py +0 -63
  148. truthound_dashboard/core/plugins/hooks/decorators.py +0 -367
  149. truthound_dashboard/core/plugins/hooks/manager.py +0 -403
  150. truthound_dashboard/core/plugins/hooks/protocols.py +0 -265
  151. truthound_dashboard/core/plugins/lifecycle/hot_reload.py +0 -584
  152. truthound_dashboard/core/reporters/junit_reporter.py +0 -233
  153. truthound_dashboard/core/reporters/markdown_reporter.py +0 -207
  154. truthound_dashboard/core/reporters/pdf_reporter.py +0 -209
  155. truthound_dashboard/static/assets/_baseUniq-BcrSP13d.js +0 -1
  156. truthound_dashboard/static/assets/arc-DlYjKwIL.js +0 -1
  157. truthound_dashboard/static/assets/architectureDiagram-VXUJARFQ-Bb2drbQM.js +0 -36
  158. truthound_dashboard/static/assets/blockDiagram-VD42YOAC-BlsPG1CH.js +0 -122
  159. truthound_dashboard/static/assets/c4Diagram-YG6GDRKO-B9JdUoaC.js +0 -10
  160. truthound_dashboard/static/assets/channel-Q6mHF1Hd.js +0 -1
  161. truthound_dashboard/static/assets/chunk-4BX2VUAB-DmyoPVuJ.js +0 -1
  162. truthound_dashboard/static/assets/chunk-55IACEB6-Bcz6Siv8.js +0 -1
  163. truthound_dashboard/static/assets/chunk-B4BG7PRW-Br3G5Rum.js +0 -165
  164. truthound_dashboard/static/assets/chunk-DI55MBZ5-DuM9c23u.js +0 -220
  165. truthound_dashboard/static/assets/chunk-FMBD7UC4-DNU-5mvT.js +0 -15
  166. truthound_dashboard/static/assets/chunk-QN33PNHL-Im2yNcmS.js +0 -1
  167. truthound_dashboard/static/assets/chunk-QZHKN3VN-kZr8XFm1.js +0 -1
  168. truthound_dashboard/static/assets/chunk-TZMSLE5B-Q__360q_.js +0 -1
  169. truthound_dashboard/static/assets/classDiagram-2ON5EDUG-vtixxUyK.js +0 -1
  170. truthound_dashboard/static/assets/classDiagram-v2-WZHVMYZB-vtixxUyK.js +0 -1
  171. truthound_dashboard/static/assets/clone-BOt2LwD0.js +0 -1
  172. truthound_dashboard/static/assets/cose-bilkent-S5V4N54A-CBDw6iac.js +0 -1
  173. truthound_dashboard/static/assets/dagre-6UL2VRFP-XdKqmmY9.js +0 -4
  174. truthound_dashboard/static/assets/diagram-PSM6KHXK-DAZ8nx9V.js +0 -24
  175. truthound_dashboard/static/assets/diagram-QEK2KX5R-BRvDTbGD.js +0 -43
  176. truthound_dashboard/static/assets/diagram-S2PKOQOG-bQcczUkl.js +0 -24
  177. truthound_dashboard/static/assets/erDiagram-Q2GNP2WA-DPje7VMN.js +0 -60
  178. truthound_dashboard/static/assets/flowDiagram-NV44I4VS-B7BVtFVS.js +0 -162
  179. truthound_dashboard/static/assets/ganttDiagram-JELNMOA3-D6WKSS7U.js +0 -267
  180. truthound_dashboard/static/assets/gitGraphDiagram-NY62KEGX-D3vtVd3y.js +0 -65
  181. truthound_dashboard/static/assets/graph-BKgNKZVp.js +0 -1
  182. truthound_dashboard/static/assets/index-C6JSrkHo.css +0 -1
  183. truthound_dashboard/static/assets/index-DkU82VsU.js +0 -1800
  184. truthound_dashboard/static/assets/infoDiagram-WHAUD3N6-DnNCT429.js +0 -2
  185. truthound_dashboard/static/assets/journeyDiagram-XKPGCS4Q-DGiMozqS.js +0 -139
  186. truthound_dashboard/static/assets/kanban-definition-3W4ZIXB7-BV2gUgli.js +0 -89
  187. truthound_dashboard/static/assets/katex-Cu_Erd72.js +0 -261
  188. truthound_dashboard/static/assets/layout-DI2MfQ5G.js +0 -1
  189. truthound_dashboard/static/assets/min-DYdgXVcT.js +0 -1
  190. truthound_dashboard/static/assets/mindmap-definition-VGOIOE7T-C7x4ruxz.js +0 -68
  191. truthound_dashboard/static/assets/pieDiagram-ADFJNKIX-CAJaAB9f.js +0 -30
  192. truthound_dashboard/static/assets/quadrantDiagram-AYHSOK5B-DeqwDI46.js +0 -7
  193. truthound_dashboard/static/assets/requirementDiagram-UZGBJVZJ-e3XDpZIM.js +0 -64
  194. truthound_dashboard/static/assets/sankeyDiagram-TZEHDZUN-CNnAv5Ux.js +0 -10
  195. truthound_dashboard/static/assets/sequenceDiagram-WL72ISMW-Dsne-Of3.js +0 -145
  196. truthound_dashboard/static/assets/stateDiagram-FKZM4ZOC-Ee0sQXyb.js +0 -1
  197. truthound_dashboard/static/assets/stateDiagram-v2-4FDKWEC3-B26KqW_W.js +0 -1
  198. truthound_dashboard/static/assets/timeline-definition-IT6M3QCI-DZYi2yl3.js +0 -61
  199. truthound_dashboard/static/assets/treemap-KMMF4GRG-CY3f8In2.js +0 -128
  200. truthound_dashboard/static/assets/unmerged_dictionaries-Dd7xcPWG.js +0 -1
  201. truthound_dashboard/static/assets/xychartDiagram-PRI3JC2R-CS7fydZZ.js +0 -7
  202. truthound_dashboard-1.4.4.dist-info/METADATA +0 -507
  203. {truthound_dashboard-1.4.4.dist-info → truthound_dashboard-1.5.0.dist-info}/WHEEL +0 -0
  204. {truthound_dashboard-1.4.4.dist-info → truthound_dashboard-1.5.0.dist-info}/entry_points.txt +0 -0
  205. {truthound_dashboard-1.4.4.dist-info → truthound_dashboard-1.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,11 @@
1
1
  """Drift detection API endpoints.
2
2
 
3
3
  Provides endpoints for drift comparison between datasets.
4
+
5
+ API Design: Direct Response Style
6
+ - Single resources return the resource directly
7
+ - List endpoints return PaginatedResponse with data, total, offset, limit
8
+ - Errors are handled via HTTPException
4
9
  """
5
10
 
6
11
  from __future__ import annotations
@@ -13,6 +18,7 @@ from truthound_dashboard.core import DriftService
13
18
  from truthound_dashboard.schemas import (
14
19
  DriftCompareRequest,
15
20
  DriftComparisonListResponse,
21
+ DriftComparisonResponse,
16
22
  )
17
23
 
18
24
  from .deps import SessionDep
@@ -28,16 +34,34 @@ async def get_drift_service(session: SessionDep) -> DriftService:
28
34
  DriftServiceDep = Annotated[DriftService, Depends(get_drift_service)]
29
35
 
30
36
 
37
+ def _comparison_to_response(comparison) -> DriftComparisonResponse:
38
+ """Convert comparison model to response schema."""
39
+ return DriftComparisonResponse(
40
+ id=comparison.id,
41
+ baseline_source_id=comparison.baseline_source_id,
42
+ current_source_id=comparison.current_source_id,
43
+ has_drift=comparison.has_drift,
44
+ has_high_drift=comparison.has_high_drift,
45
+ total_columns=comparison.total_columns,
46
+ drifted_columns=comparison.drifted_columns,
47
+ drift_percentage=comparison.drift_percentage,
48
+ result=comparison.result_json,
49
+ config=comparison.config,
50
+ created_at=comparison.created_at,
51
+ updated_at=comparison.updated_at,
52
+ )
53
+
54
+
31
55
  @router.post(
32
56
  "/drift/compare",
33
- response_model=dict,
57
+ response_model=DriftComparisonResponse,
34
58
  summary="Compare datasets for drift",
35
59
  description="Compare two datasets to detect data drift.",
36
60
  )
37
61
  async def compare_datasets(
38
62
  request: DriftCompareRequest,
39
63
  service: DriftServiceDep,
40
- ) -> dict:
64
+ ) -> DriftComparisonResponse:
41
65
  """Compare two datasets for drift detection.
42
66
 
43
67
  Args:
@@ -54,28 +78,9 @@ async def compare_datasets(
54
78
  columns=request.columns,
55
79
  method=request.method,
56
80
  threshold=request.threshold,
57
- correction=request.correction,
58
81
  sample_size=request.sample_size,
59
82
  )
60
-
61
- return {
62
- "success": True,
63
- "data": {
64
- "id": comparison.id,
65
- "baseline_source_id": comparison.baseline_source_id,
66
- "current_source_id": comparison.current_source_id,
67
- "has_drift": comparison.has_drift,
68
- "has_high_drift": comparison.has_high_drift,
69
- "total_columns": comparison.total_columns,
70
- "drifted_columns": comparison.drifted_columns,
71
- "drift_percentage": comparison.drift_percentage,
72
- "result": comparison.result_json,
73
- "config": comparison.config,
74
- "created_at": (
75
- comparison.created_at.isoformat() if comparison.created_at else None
76
- ),
77
- },
78
- }
83
+ return _comparison_to_response(comparison)
79
84
  except ValueError as e:
80
85
  raise HTTPException(status_code=404, detail=str(e))
81
86
  except Exception as e:
@@ -94,6 +99,7 @@ async def list_comparisons(
94
99
  None, description="Filter by baseline source"
95
100
  ),
96
101
  current_source_id: str | None = Query(None, description="Filter by current source"),
102
+ offset: int = Query(0, ge=0, description="Offset for pagination"),
97
103
  limit: int = Query(20, ge=1, le=100, description="Maximum results"),
98
104
  ) -> DriftComparisonListResponse:
99
105
  """List drift comparisons.
@@ -102,10 +108,11 @@ async def list_comparisons(
102
108
  service: Drift service.
103
109
  baseline_source_id: Optional baseline source ID filter.
104
110
  current_source_id: Optional current source ID filter.
111
+ offset: Offset for pagination.
105
112
  limit: Maximum results to return.
106
113
 
107
114
  Returns:
108
- List of drift comparisons.
115
+ Paginated list of drift comparisons.
109
116
  """
110
117
  comparisons = await service.list_comparisons(
111
118
  baseline_source_id=baseline_source_id,
@@ -113,37 +120,40 @@ async def list_comparisons(
113
120
  limit=limit,
114
121
  )
115
122
 
123
+ from truthound_dashboard.schemas.drift import DriftComparisonListItem
124
+
116
125
  return DriftComparisonListResponse(
117
- success=True,
118
126
  data=[
119
- {
120
- "id": c.id,
121
- "baseline_source_id": c.baseline_source_id,
122
- "current_source_id": c.current_source_id,
123
- "has_drift": c.has_drift,
124
- "has_high_drift": c.has_high_drift,
125
- "total_columns": c.total_columns,
126
- "drifted_columns": c.drifted_columns,
127
- "drift_percentage": c.drift_percentage,
128
- "created_at": c.created_at.isoformat() if c.created_at else None,
129
- "updated_at": c.updated_at.isoformat() if c.updated_at else None,
130
- }
127
+ DriftComparisonListItem(
128
+ id=c.id,
129
+ baseline_source_id=c.baseline_source_id,
130
+ current_source_id=c.current_source_id,
131
+ has_drift=c.has_drift,
132
+ has_high_drift=c.has_high_drift,
133
+ total_columns=c.total_columns,
134
+ drifted_columns=c.drifted_columns,
135
+ drift_percentage=c.drift_percentage,
136
+ created_at=c.created_at,
137
+ updated_at=c.updated_at,
138
+ )
131
139
  for c in comparisons
132
140
  ],
133
141
  total=len(comparisons),
142
+ offset=offset,
143
+ limit=limit,
134
144
  )
135
145
 
136
146
 
137
147
  @router.get(
138
148
  "/drift/comparisons/{comparison_id}",
139
- response_model=dict,
149
+ response_model=DriftComparisonResponse,
140
150
  summary="Get drift comparison",
141
151
  description="Get a specific drift comparison by ID.",
142
152
  )
143
153
  async def get_comparison(
144
154
  comparison_id: str,
145
155
  service: DriftServiceDep,
146
- ) -> dict:
156
+ ) -> DriftComparisonResponse:
147
157
  """Get a drift comparison by ID.
148
158
 
149
159
  Args:
@@ -157,24 +167,4 @@ async def get_comparison(
157
167
  if comparison is None:
158
168
  raise HTTPException(status_code=404, detail="Comparison not found")
159
169
 
160
- return {
161
- "success": True,
162
- "data": {
163
- "id": comparison.id,
164
- "baseline_source_id": comparison.baseline_source_id,
165
- "current_source_id": comparison.current_source_id,
166
- "has_drift": comparison.has_drift,
167
- "has_high_drift": comparison.has_high_drift,
168
- "total_columns": comparison.total_columns,
169
- "drifted_columns": comparison.drifted_columns,
170
- "drift_percentage": comparison.drift_percentage,
171
- "result": comparison.result_json,
172
- "config": comparison.config,
173
- "created_at": (
174
- comparison.created_at.isoformat() if comparison.created_at else None
175
- ),
176
- "updated_at": (
177
- comparison.updated_at.isoformat() if comparison.updated_at else None
178
- ),
179
- },
180
- }
170
+ return _comparison_to_response(comparison)