truthound 1.0.8__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 (877) hide show
  1. truthound/__init__.py +162 -0
  2. truthound/adapters.py +100 -0
  3. truthound/api.py +365 -0
  4. truthound/audit/__init__.py +248 -0
  5. truthound/audit/core.py +967 -0
  6. truthound/audit/filters.py +620 -0
  7. truthound/audit/formatters.py +707 -0
  8. truthound/audit/logger.py +902 -0
  9. truthound/audit/middleware.py +571 -0
  10. truthound/audit/storage.py +1083 -0
  11. truthound/benchmark/__init__.py +123 -0
  12. truthound/benchmark/base.py +757 -0
  13. truthound/benchmark/comparison.py +635 -0
  14. truthound/benchmark/generators.py +706 -0
  15. truthound/benchmark/reporters.py +718 -0
  16. truthound/benchmark/runner.py +635 -0
  17. truthound/benchmark/scenarios.py +712 -0
  18. truthound/cache.py +252 -0
  19. truthound/checkpoint/__init__.py +136 -0
  20. truthound/checkpoint/actions/__init__.py +164 -0
  21. truthound/checkpoint/actions/base.py +324 -0
  22. truthound/checkpoint/actions/custom.py +234 -0
  23. truthound/checkpoint/actions/discord_notify.py +290 -0
  24. truthound/checkpoint/actions/email_notify.py +405 -0
  25. truthound/checkpoint/actions/github_action.py +406 -0
  26. truthound/checkpoint/actions/opsgenie.py +1499 -0
  27. truthound/checkpoint/actions/pagerduty.py +226 -0
  28. truthound/checkpoint/actions/slack_notify.py +233 -0
  29. truthound/checkpoint/actions/store_result.py +249 -0
  30. truthound/checkpoint/actions/teams_notify.py +1570 -0
  31. truthound/checkpoint/actions/telegram_notify.py +419 -0
  32. truthound/checkpoint/actions/update_docs.py +552 -0
  33. truthound/checkpoint/actions/webhook.py +293 -0
  34. truthound/checkpoint/analytics/__init__.py +147 -0
  35. truthound/checkpoint/analytics/aggregations/__init__.py +23 -0
  36. truthound/checkpoint/analytics/aggregations/rollup.py +481 -0
  37. truthound/checkpoint/analytics/aggregations/time_bucket.py +306 -0
  38. truthound/checkpoint/analytics/analyzers/__init__.py +17 -0
  39. truthound/checkpoint/analytics/analyzers/anomaly.py +386 -0
  40. truthound/checkpoint/analytics/analyzers/base.py +270 -0
  41. truthound/checkpoint/analytics/analyzers/forecast.py +421 -0
  42. truthound/checkpoint/analytics/analyzers/trend.py +314 -0
  43. truthound/checkpoint/analytics/models.py +292 -0
  44. truthound/checkpoint/analytics/protocols.py +549 -0
  45. truthound/checkpoint/analytics/service.py +718 -0
  46. truthound/checkpoint/analytics/stores/__init__.py +16 -0
  47. truthound/checkpoint/analytics/stores/base.py +306 -0
  48. truthound/checkpoint/analytics/stores/memory_store.py +353 -0
  49. truthound/checkpoint/analytics/stores/sqlite_store.py +557 -0
  50. truthound/checkpoint/analytics/stores/timescale_store.py +501 -0
  51. truthound/checkpoint/async_actions.py +794 -0
  52. truthound/checkpoint/async_base.py +708 -0
  53. truthound/checkpoint/async_checkpoint.py +617 -0
  54. truthound/checkpoint/async_runner.py +639 -0
  55. truthound/checkpoint/checkpoint.py +527 -0
  56. truthound/checkpoint/ci/__init__.py +61 -0
  57. truthound/checkpoint/ci/detector.py +355 -0
  58. truthound/checkpoint/ci/reporter.py +436 -0
  59. truthound/checkpoint/ci/templates.py +454 -0
  60. truthound/checkpoint/circuitbreaker/__init__.py +133 -0
  61. truthound/checkpoint/circuitbreaker/breaker.py +542 -0
  62. truthound/checkpoint/circuitbreaker/core.py +252 -0
  63. truthound/checkpoint/circuitbreaker/detection.py +459 -0
  64. truthound/checkpoint/circuitbreaker/middleware.py +389 -0
  65. truthound/checkpoint/circuitbreaker/registry.py +357 -0
  66. truthound/checkpoint/distributed/__init__.py +139 -0
  67. truthound/checkpoint/distributed/backends/__init__.py +35 -0
  68. truthound/checkpoint/distributed/backends/celery_backend.py +503 -0
  69. truthound/checkpoint/distributed/backends/kubernetes_backend.py +696 -0
  70. truthound/checkpoint/distributed/backends/local_backend.py +397 -0
  71. truthound/checkpoint/distributed/backends/ray_backend.py +625 -0
  72. truthound/checkpoint/distributed/base.py +774 -0
  73. truthound/checkpoint/distributed/orchestrator.py +765 -0
  74. truthound/checkpoint/distributed/protocols.py +842 -0
  75. truthound/checkpoint/distributed/registry.py +449 -0
  76. truthound/checkpoint/idempotency/__init__.py +120 -0
  77. truthound/checkpoint/idempotency/core.py +295 -0
  78. truthound/checkpoint/idempotency/fingerprint.py +454 -0
  79. truthound/checkpoint/idempotency/locking.py +604 -0
  80. truthound/checkpoint/idempotency/service.py +592 -0
  81. truthound/checkpoint/idempotency/stores.py +653 -0
  82. truthound/checkpoint/monitoring/__init__.py +134 -0
  83. truthound/checkpoint/monitoring/aggregators/__init__.py +15 -0
  84. truthound/checkpoint/monitoring/aggregators/base.py +372 -0
  85. truthound/checkpoint/monitoring/aggregators/realtime.py +300 -0
  86. truthound/checkpoint/monitoring/aggregators/window.py +493 -0
  87. truthound/checkpoint/monitoring/collectors/__init__.py +17 -0
  88. truthound/checkpoint/monitoring/collectors/base.py +257 -0
  89. truthound/checkpoint/monitoring/collectors/memory_collector.py +617 -0
  90. truthound/checkpoint/monitoring/collectors/prometheus_collector.py +451 -0
  91. truthound/checkpoint/monitoring/collectors/redis_collector.py +518 -0
  92. truthound/checkpoint/monitoring/events.py +410 -0
  93. truthound/checkpoint/monitoring/protocols.py +636 -0
  94. truthound/checkpoint/monitoring/service.py +578 -0
  95. truthound/checkpoint/monitoring/views/__init__.py +17 -0
  96. truthound/checkpoint/monitoring/views/base.py +172 -0
  97. truthound/checkpoint/monitoring/views/queue_view.py +220 -0
  98. truthound/checkpoint/monitoring/views/task_view.py +240 -0
  99. truthound/checkpoint/monitoring/views/worker_view.py +263 -0
  100. truthound/checkpoint/registry.py +337 -0
  101. truthound/checkpoint/runner.py +356 -0
  102. truthound/checkpoint/transaction/__init__.py +133 -0
  103. truthound/checkpoint/transaction/base.py +389 -0
  104. truthound/checkpoint/transaction/compensatable.py +537 -0
  105. truthound/checkpoint/transaction/coordinator.py +576 -0
  106. truthound/checkpoint/transaction/executor.py +622 -0
  107. truthound/checkpoint/transaction/idempotency.py +534 -0
  108. truthound/checkpoint/transaction/saga/__init__.py +143 -0
  109. truthound/checkpoint/transaction/saga/builder.py +584 -0
  110. truthound/checkpoint/transaction/saga/definition.py +515 -0
  111. truthound/checkpoint/transaction/saga/event_store.py +542 -0
  112. truthound/checkpoint/transaction/saga/patterns.py +833 -0
  113. truthound/checkpoint/transaction/saga/runner.py +718 -0
  114. truthound/checkpoint/transaction/saga/state_machine.py +793 -0
  115. truthound/checkpoint/transaction/saga/strategies.py +780 -0
  116. truthound/checkpoint/transaction/saga/testing.py +886 -0
  117. truthound/checkpoint/triggers/__init__.py +58 -0
  118. truthound/checkpoint/triggers/base.py +237 -0
  119. truthound/checkpoint/triggers/event.py +385 -0
  120. truthound/checkpoint/triggers/schedule.py +355 -0
  121. truthound/cli.py +2358 -0
  122. truthound/cli_modules/__init__.py +124 -0
  123. truthound/cli_modules/advanced/__init__.py +45 -0
  124. truthound/cli_modules/advanced/benchmark.py +343 -0
  125. truthound/cli_modules/advanced/docs.py +225 -0
  126. truthound/cli_modules/advanced/lineage.py +209 -0
  127. truthound/cli_modules/advanced/ml.py +320 -0
  128. truthound/cli_modules/advanced/realtime.py +196 -0
  129. truthound/cli_modules/checkpoint/__init__.py +46 -0
  130. truthound/cli_modules/checkpoint/init.py +114 -0
  131. truthound/cli_modules/checkpoint/list.py +71 -0
  132. truthound/cli_modules/checkpoint/run.py +159 -0
  133. truthound/cli_modules/checkpoint/validate.py +67 -0
  134. truthound/cli_modules/common/__init__.py +71 -0
  135. truthound/cli_modules/common/errors.py +414 -0
  136. truthound/cli_modules/common/options.py +419 -0
  137. truthound/cli_modules/common/output.py +507 -0
  138. truthound/cli_modules/common/protocol.py +552 -0
  139. truthound/cli_modules/core/__init__.py +48 -0
  140. truthound/cli_modules/core/check.py +123 -0
  141. truthound/cli_modules/core/compare.py +104 -0
  142. truthound/cli_modules/core/learn.py +57 -0
  143. truthound/cli_modules/core/mask.py +77 -0
  144. truthound/cli_modules/core/profile.py +65 -0
  145. truthound/cli_modules/core/scan.py +61 -0
  146. truthound/cli_modules/profiler/__init__.py +51 -0
  147. truthound/cli_modules/profiler/auto_profile.py +175 -0
  148. truthound/cli_modules/profiler/metadata.py +107 -0
  149. truthound/cli_modules/profiler/suite.py +283 -0
  150. truthound/cli_modules/registry.py +431 -0
  151. truthound/cli_modules/scaffolding/__init__.py +89 -0
  152. truthound/cli_modules/scaffolding/base.py +631 -0
  153. truthound/cli_modules/scaffolding/commands.py +545 -0
  154. truthound/cli_modules/scaffolding/plugins.py +1072 -0
  155. truthound/cli_modules/scaffolding/reporters.py +594 -0
  156. truthound/cli_modules/scaffolding/validators.py +1127 -0
  157. truthound/common/__init__.py +18 -0
  158. truthound/common/resilience/__init__.py +130 -0
  159. truthound/common/resilience/bulkhead.py +266 -0
  160. truthound/common/resilience/circuit_breaker.py +516 -0
  161. truthound/common/resilience/composite.py +332 -0
  162. truthound/common/resilience/config.py +292 -0
  163. truthound/common/resilience/protocols.py +217 -0
  164. truthound/common/resilience/rate_limiter.py +404 -0
  165. truthound/common/resilience/retry.py +341 -0
  166. truthound/datadocs/__init__.py +260 -0
  167. truthound/datadocs/base.py +571 -0
  168. truthound/datadocs/builder.py +761 -0
  169. truthound/datadocs/charts.py +764 -0
  170. truthound/datadocs/dashboard/__init__.py +63 -0
  171. truthound/datadocs/dashboard/app.py +576 -0
  172. truthound/datadocs/dashboard/components.py +584 -0
  173. truthound/datadocs/dashboard/state.py +240 -0
  174. truthound/datadocs/engine/__init__.py +46 -0
  175. truthound/datadocs/engine/context.py +376 -0
  176. truthound/datadocs/engine/pipeline.py +618 -0
  177. truthound/datadocs/engine/registry.py +469 -0
  178. truthound/datadocs/exporters/__init__.py +49 -0
  179. truthound/datadocs/exporters/base.py +198 -0
  180. truthound/datadocs/exporters/html.py +178 -0
  181. truthound/datadocs/exporters/json_exporter.py +253 -0
  182. truthound/datadocs/exporters/markdown.py +284 -0
  183. truthound/datadocs/exporters/pdf.py +392 -0
  184. truthound/datadocs/i18n/__init__.py +86 -0
  185. truthound/datadocs/i18n/catalog.py +960 -0
  186. truthound/datadocs/i18n/formatting.py +505 -0
  187. truthound/datadocs/i18n/loader.py +256 -0
  188. truthound/datadocs/i18n/plurals.py +378 -0
  189. truthound/datadocs/renderers/__init__.py +42 -0
  190. truthound/datadocs/renderers/base.py +401 -0
  191. truthound/datadocs/renderers/custom.py +342 -0
  192. truthound/datadocs/renderers/jinja.py +697 -0
  193. truthound/datadocs/sections.py +736 -0
  194. truthound/datadocs/styles.py +931 -0
  195. truthound/datadocs/themes/__init__.py +101 -0
  196. truthound/datadocs/themes/base.py +336 -0
  197. truthound/datadocs/themes/default.py +417 -0
  198. truthound/datadocs/themes/enterprise.py +419 -0
  199. truthound/datadocs/themes/loader.py +336 -0
  200. truthound/datadocs/themes.py +301 -0
  201. truthound/datadocs/transformers/__init__.py +57 -0
  202. truthound/datadocs/transformers/base.py +268 -0
  203. truthound/datadocs/transformers/enrichers.py +544 -0
  204. truthound/datadocs/transformers/filters.py +447 -0
  205. truthound/datadocs/transformers/i18n.py +468 -0
  206. truthound/datadocs/versioning/__init__.py +62 -0
  207. truthound/datadocs/versioning/diff.py +639 -0
  208. truthound/datadocs/versioning/storage.py +497 -0
  209. truthound/datadocs/versioning/version.py +358 -0
  210. truthound/datasources/__init__.py +223 -0
  211. truthound/datasources/_async_protocols.py +222 -0
  212. truthound/datasources/_protocols.py +159 -0
  213. truthound/datasources/adapters.py +428 -0
  214. truthound/datasources/async_base.py +599 -0
  215. truthound/datasources/async_factory.py +511 -0
  216. truthound/datasources/base.py +516 -0
  217. truthound/datasources/factory.py +433 -0
  218. truthound/datasources/nosql/__init__.py +47 -0
  219. truthound/datasources/nosql/base.py +487 -0
  220. truthound/datasources/nosql/elasticsearch.py +801 -0
  221. truthound/datasources/nosql/mongodb.py +636 -0
  222. truthound/datasources/pandas_optimized.py +582 -0
  223. truthound/datasources/pandas_source.py +216 -0
  224. truthound/datasources/polars_source.py +395 -0
  225. truthound/datasources/spark_source.py +479 -0
  226. truthound/datasources/sql/__init__.py +154 -0
  227. truthound/datasources/sql/base.py +710 -0
  228. truthound/datasources/sql/bigquery.py +410 -0
  229. truthound/datasources/sql/cloud_base.py +199 -0
  230. truthound/datasources/sql/databricks.py +471 -0
  231. truthound/datasources/sql/mysql.py +316 -0
  232. truthound/datasources/sql/oracle.py +427 -0
  233. truthound/datasources/sql/postgresql.py +321 -0
  234. truthound/datasources/sql/redshift.py +479 -0
  235. truthound/datasources/sql/snowflake.py +439 -0
  236. truthound/datasources/sql/sqlite.py +286 -0
  237. truthound/datasources/sql/sqlserver.py +437 -0
  238. truthound/datasources/streaming/__init__.py +47 -0
  239. truthound/datasources/streaming/base.py +350 -0
  240. truthound/datasources/streaming/kafka.py +670 -0
  241. truthound/decorators.py +98 -0
  242. truthound/docs/__init__.py +69 -0
  243. truthound/docs/extractor.py +971 -0
  244. truthound/docs/generator.py +601 -0
  245. truthound/docs/parser.py +1037 -0
  246. truthound/docs/renderer.py +999 -0
  247. truthound/drift/__init__.py +22 -0
  248. truthound/drift/compare.py +189 -0
  249. truthound/drift/detectors.py +464 -0
  250. truthound/drift/report.py +160 -0
  251. truthound/execution/__init__.py +65 -0
  252. truthound/execution/_protocols.py +324 -0
  253. truthound/execution/base.py +576 -0
  254. truthound/execution/distributed/__init__.py +179 -0
  255. truthound/execution/distributed/aggregations.py +731 -0
  256. truthound/execution/distributed/arrow_bridge.py +817 -0
  257. truthound/execution/distributed/base.py +550 -0
  258. truthound/execution/distributed/dask_engine.py +976 -0
  259. truthound/execution/distributed/mixins.py +766 -0
  260. truthound/execution/distributed/protocols.py +756 -0
  261. truthound/execution/distributed/ray_engine.py +1127 -0
  262. truthound/execution/distributed/registry.py +446 -0
  263. truthound/execution/distributed/spark_engine.py +1011 -0
  264. truthound/execution/distributed/validator_adapter.py +682 -0
  265. truthound/execution/pandas_engine.py +401 -0
  266. truthound/execution/polars_engine.py +497 -0
  267. truthound/execution/pushdown/__init__.py +230 -0
  268. truthound/execution/pushdown/ast.py +1550 -0
  269. truthound/execution/pushdown/builder.py +1550 -0
  270. truthound/execution/pushdown/dialects.py +1072 -0
  271. truthound/execution/pushdown/executor.py +829 -0
  272. truthound/execution/pushdown/optimizer.py +1041 -0
  273. truthound/execution/sql_engine.py +518 -0
  274. truthound/infrastructure/__init__.py +189 -0
  275. truthound/infrastructure/audit.py +1515 -0
  276. truthound/infrastructure/config.py +1133 -0
  277. truthound/infrastructure/encryption.py +1132 -0
  278. truthound/infrastructure/logging.py +1503 -0
  279. truthound/infrastructure/metrics.py +1220 -0
  280. truthound/lineage/__init__.py +89 -0
  281. truthound/lineage/base.py +746 -0
  282. truthound/lineage/impact_analysis.py +474 -0
  283. truthound/lineage/integrations/__init__.py +22 -0
  284. truthound/lineage/integrations/openlineage.py +548 -0
  285. truthound/lineage/tracker.py +512 -0
  286. truthound/lineage/visualization/__init__.py +33 -0
  287. truthound/lineage/visualization/protocols.py +145 -0
  288. truthound/lineage/visualization/renderers/__init__.py +20 -0
  289. truthound/lineage/visualization/renderers/cytoscape.py +329 -0
  290. truthound/lineage/visualization/renderers/d3.py +331 -0
  291. truthound/lineage/visualization/renderers/graphviz.py +276 -0
  292. truthound/lineage/visualization/renderers/mermaid.py +308 -0
  293. truthound/maskers.py +113 -0
  294. truthound/ml/__init__.py +124 -0
  295. truthound/ml/anomaly_models/__init__.py +31 -0
  296. truthound/ml/anomaly_models/ensemble.py +362 -0
  297. truthound/ml/anomaly_models/isolation_forest.py +444 -0
  298. truthound/ml/anomaly_models/statistical.py +392 -0
  299. truthound/ml/base.py +1178 -0
  300. truthound/ml/drift_detection/__init__.py +26 -0
  301. truthound/ml/drift_detection/concept.py +381 -0
  302. truthound/ml/drift_detection/distribution.py +361 -0
  303. truthound/ml/drift_detection/feature.py +442 -0
  304. truthound/ml/drift_detection/multivariate.py +495 -0
  305. truthound/ml/monitoring/__init__.py +88 -0
  306. truthound/ml/monitoring/alerting/__init__.py +33 -0
  307. truthound/ml/monitoring/alerting/handlers.py +427 -0
  308. truthound/ml/monitoring/alerting/rules.py +508 -0
  309. truthound/ml/monitoring/collectors/__init__.py +19 -0
  310. truthound/ml/monitoring/collectors/composite.py +105 -0
  311. truthound/ml/monitoring/collectors/drift.py +324 -0
  312. truthound/ml/monitoring/collectors/performance.py +179 -0
  313. truthound/ml/monitoring/collectors/quality.py +369 -0
  314. truthound/ml/monitoring/monitor.py +536 -0
  315. truthound/ml/monitoring/protocols.py +451 -0
  316. truthound/ml/monitoring/stores/__init__.py +15 -0
  317. truthound/ml/monitoring/stores/memory.py +201 -0
  318. truthound/ml/monitoring/stores/prometheus.py +296 -0
  319. truthound/ml/rule_learning/__init__.py +25 -0
  320. truthound/ml/rule_learning/constraint_miner.py +443 -0
  321. truthound/ml/rule_learning/pattern_learner.py +499 -0
  322. truthound/ml/rule_learning/profile_learner.py +462 -0
  323. truthound/multitenancy/__init__.py +326 -0
  324. truthound/multitenancy/core.py +852 -0
  325. truthound/multitenancy/integration.py +597 -0
  326. truthound/multitenancy/isolation.py +630 -0
  327. truthound/multitenancy/manager.py +770 -0
  328. truthound/multitenancy/middleware.py +765 -0
  329. truthound/multitenancy/quota.py +537 -0
  330. truthound/multitenancy/resolvers.py +603 -0
  331. truthound/multitenancy/storage.py +703 -0
  332. truthound/observability/__init__.py +307 -0
  333. truthound/observability/context.py +531 -0
  334. truthound/observability/instrumentation.py +611 -0
  335. truthound/observability/logging.py +887 -0
  336. truthound/observability/metrics.py +1157 -0
  337. truthound/observability/tracing/__init__.py +178 -0
  338. truthound/observability/tracing/baggage.py +310 -0
  339. truthound/observability/tracing/config.py +426 -0
  340. truthound/observability/tracing/exporter.py +787 -0
  341. truthound/observability/tracing/integration.py +1018 -0
  342. truthound/observability/tracing/otel/__init__.py +146 -0
  343. truthound/observability/tracing/otel/adapter.py +982 -0
  344. truthound/observability/tracing/otel/bridge.py +1177 -0
  345. truthound/observability/tracing/otel/compat.py +681 -0
  346. truthound/observability/tracing/otel/config.py +691 -0
  347. truthound/observability/tracing/otel/detection.py +327 -0
  348. truthound/observability/tracing/otel/protocols.py +426 -0
  349. truthound/observability/tracing/processor.py +561 -0
  350. truthound/observability/tracing/propagator.py +757 -0
  351. truthound/observability/tracing/provider.py +569 -0
  352. truthound/observability/tracing/resource.py +515 -0
  353. truthound/observability/tracing/sampler.py +487 -0
  354. truthound/observability/tracing/span.py +676 -0
  355. truthound/plugins/__init__.py +198 -0
  356. truthound/plugins/base.py +599 -0
  357. truthound/plugins/cli.py +680 -0
  358. truthound/plugins/dependencies/__init__.py +42 -0
  359. truthound/plugins/dependencies/graph.py +422 -0
  360. truthound/plugins/dependencies/resolver.py +417 -0
  361. truthound/plugins/discovery.py +379 -0
  362. truthound/plugins/docs/__init__.py +46 -0
  363. truthound/plugins/docs/extractor.py +444 -0
  364. truthound/plugins/docs/renderer.py +499 -0
  365. truthound/plugins/enterprise_manager.py +877 -0
  366. truthound/plugins/examples/__init__.py +19 -0
  367. truthound/plugins/examples/custom_validators.py +317 -0
  368. truthound/plugins/examples/slack_notifier.py +312 -0
  369. truthound/plugins/examples/xml_reporter.py +254 -0
  370. truthound/plugins/hooks.py +558 -0
  371. truthound/plugins/lifecycle/__init__.py +43 -0
  372. truthound/plugins/lifecycle/hot_reload.py +402 -0
  373. truthound/plugins/lifecycle/manager.py +371 -0
  374. truthound/plugins/manager.py +736 -0
  375. truthound/plugins/registry.py +338 -0
  376. truthound/plugins/security/__init__.py +93 -0
  377. truthound/plugins/security/exceptions.py +332 -0
  378. truthound/plugins/security/policies.py +348 -0
  379. truthound/plugins/security/protocols.py +643 -0
  380. truthound/plugins/security/sandbox/__init__.py +45 -0
  381. truthound/plugins/security/sandbox/context.py +158 -0
  382. truthound/plugins/security/sandbox/engines/__init__.py +19 -0
  383. truthound/plugins/security/sandbox/engines/container.py +379 -0
  384. truthound/plugins/security/sandbox/engines/noop.py +144 -0
  385. truthound/plugins/security/sandbox/engines/process.py +336 -0
  386. truthound/plugins/security/sandbox/factory.py +211 -0
  387. truthound/plugins/security/signing/__init__.py +57 -0
  388. truthound/plugins/security/signing/service.py +330 -0
  389. truthound/plugins/security/signing/trust_store.py +368 -0
  390. truthound/plugins/security/signing/verifier.py +459 -0
  391. truthound/plugins/versioning/__init__.py +41 -0
  392. truthound/plugins/versioning/constraints.py +297 -0
  393. truthound/plugins/versioning/resolver.py +329 -0
  394. truthound/profiler/__init__.py +1729 -0
  395. truthound/profiler/_lazy.py +452 -0
  396. truthound/profiler/ab_testing/__init__.py +80 -0
  397. truthound/profiler/ab_testing/analysis.py +449 -0
  398. truthound/profiler/ab_testing/base.py +257 -0
  399. truthound/profiler/ab_testing/experiment.py +395 -0
  400. truthound/profiler/ab_testing/tracking.py +368 -0
  401. truthound/profiler/auto_threshold.py +1170 -0
  402. truthound/profiler/base.py +579 -0
  403. truthound/profiler/cache_patterns.py +911 -0
  404. truthound/profiler/caching.py +1303 -0
  405. truthound/profiler/column_profiler.py +712 -0
  406. truthound/profiler/comparison.py +1007 -0
  407. truthound/profiler/custom_patterns.py +1170 -0
  408. truthound/profiler/dashboard/__init__.py +50 -0
  409. truthound/profiler/dashboard/app.py +476 -0
  410. truthound/profiler/dashboard/components.py +457 -0
  411. truthound/profiler/dashboard/config.py +72 -0
  412. truthound/profiler/distributed/__init__.py +83 -0
  413. truthound/profiler/distributed/base.py +281 -0
  414. truthound/profiler/distributed/dask_backend.py +498 -0
  415. truthound/profiler/distributed/local_backend.py +293 -0
  416. truthound/profiler/distributed/profiler.py +304 -0
  417. truthound/profiler/distributed/ray_backend.py +374 -0
  418. truthound/profiler/distributed/spark_backend.py +375 -0
  419. truthound/profiler/distributed.py +1366 -0
  420. truthound/profiler/enterprise_sampling.py +1065 -0
  421. truthound/profiler/errors.py +488 -0
  422. truthound/profiler/evolution/__init__.py +91 -0
  423. truthound/profiler/evolution/alerts.py +426 -0
  424. truthound/profiler/evolution/changes.py +206 -0
  425. truthound/profiler/evolution/compatibility.py +365 -0
  426. truthound/profiler/evolution/detector.py +372 -0
  427. truthound/profiler/evolution/protocols.py +121 -0
  428. truthound/profiler/generators/__init__.py +48 -0
  429. truthound/profiler/generators/base.py +384 -0
  430. truthound/profiler/generators/ml_rules.py +375 -0
  431. truthound/profiler/generators/pattern_rules.py +384 -0
  432. truthound/profiler/generators/schema_rules.py +267 -0
  433. truthound/profiler/generators/stats_rules.py +324 -0
  434. truthound/profiler/generators/suite_generator.py +857 -0
  435. truthound/profiler/i18n.py +1542 -0
  436. truthound/profiler/incremental.py +554 -0
  437. truthound/profiler/incremental_validation.py +1710 -0
  438. truthound/profiler/integration/__init__.py +73 -0
  439. truthound/profiler/integration/adapters.py +345 -0
  440. truthound/profiler/integration/context.py +371 -0
  441. truthound/profiler/integration/executor.py +527 -0
  442. truthound/profiler/integration/naming.py +75 -0
  443. truthound/profiler/integration/protocols.py +243 -0
  444. truthound/profiler/memory.py +1185 -0
  445. truthound/profiler/migration/__init__.py +60 -0
  446. truthound/profiler/migration/base.py +345 -0
  447. truthound/profiler/migration/manager.py +444 -0
  448. truthound/profiler/migration/v1_0_to_v1_1.py +484 -0
  449. truthound/profiler/ml/__init__.py +73 -0
  450. truthound/profiler/ml/base.py +244 -0
  451. truthound/profiler/ml/classifier.py +507 -0
  452. truthound/profiler/ml/feature_extraction.py +604 -0
  453. truthound/profiler/ml/pretrained.py +448 -0
  454. truthound/profiler/ml_inference.py +1276 -0
  455. truthound/profiler/native_patterns.py +815 -0
  456. truthound/profiler/observability.py +1184 -0
  457. truthound/profiler/process_timeout.py +1566 -0
  458. truthound/profiler/progress.py +568 -0
  459. truthound/profiler/progress_callbacks.py +1734 -0
  460. truthound/profiler/quality.py +1345 -0
  461. truthound/profiler/resilience.py +1180 -0
  462. truthound/profiler/sampled_matcher.py +794 -0
  463. truthound/profiler/sampling.py +1288 -0
  464. truthound/profiler/scheduling/__init__.py +82 -0
  465. truthound/profiler/scheduling/protocols.py +214 -0
  466. truthound/profiler/scheduling/scheduler.py +474 -0
  467. truthound/profiler/scheduling/storage.py +457 -0
  468. truthound/profiler/scheduling/triggers.py +449 -0
  469. truthound/profiler/schema.py +603 -0
  470. truthound/profiler/streaming.py +685 -0
  471. truthound/profiler/streaming_patterns.py +1354 -0
  472. truthound/profiler/suite_cli.py +625 -0
  473. truthound/profiler/suite_config.py +789 -0
  474. truthound/profiler/suite_export.py +1268 -0
  475. truthound/profiler/table_profiler.py +547 -0
  476. truthound/profiler/timeout.py +565 -0
  477. truthound/profiler/validation.py +1532 -0
  478. truthound/profiler/visualization/__init__.py +118 -0
  479. truthound/profiler/visualization/base.py +346 -0
  480. truthound/profiler/visualization/generator.py +1259 -0
  481. truthound/profiler/visualization/plotly_renderer.py +811 -0
  482. truthound/profiler/visualization/renderers.py +669 -0
  483. truthound/profiler/visualization/sections.py +540 -0
  484. truthound/profiler/visualization.py +2122 -0
  485. truthound/profiler/yaml_validation.py +1151 -0
  486. truthound/py.typed +0 -0
  487. truthound/ratelimit/__init__.py +248 -0
  488. truthound/ratelimit/algorithms.py +1108 -0
  489. truthound/ratelimit/core.py +573 -0
  490. truthound/ratelimit/integration.py +532 -0
  491. truthound/ratelimit/limiter.py +663 -0
  492. truthound/ratelimit/middleware.py +700 -0
  493. truthound/ratelimit/policy.py +792 -0
  494. truthound/ratelimit/storage.py +763 -0
  495. truthound/rbac/__init__.py +340 -0
  496. truthound/rbac/core.py +976 -0
  497. truthound/rbac/integration.py +760 -0
  498. truthound/rbac/manager.py +1052 -0
  499. truthound/rbac/middleware.py +842 -0
  500. truthound/rbac/policy.py +954 -0
  501. truthound/rbac/storage.py +878 -0
  502. truthound/realtime/__init__.py +141 -0
  503. truthound/realtime/adapters/__init__.py +43 -0
  504. truthound/realtime/adapters/base.py +533 -0
  505. truthound/realtime/adapters/kafka.py +487 -0
  506. truthound/realtime/adapters/kinesis.py +479 -0
  507. truthound/realtime/adapters/mock.py +243 -0
  508. truthound/realtime/base.py +553 -0
  509. truthound/realtime/factory.py +382 -0
  510. truthound/realtime/incremental.py +660 -0
  511. truthound/realtime/processing/__init__.py +67 -0
  512. truthound/realtime/processing/exactly_once.py +575 -0
  513. truthound/realtime/processing/state.py +547 -0
  514. truthound/realtime/processing/windows.py +647 -0
  515. truthound/realtime/protocols.py +569 -0
  516. truthound/realtime/streaming.py +605 -0
  517. truthound/realtime/testing/__init__.py +32 -0
  518. truthound/realtime/testing/containers.py +615 -0
  519. truthound/realtime/testing/fixtures.py +484 -0
  520. truthound/report.py +280 -0
  521. truthound/reporters/__init__.py +46 -0
  522. truthound/reporters/_protocols.py +30 -0
  523. truthound/reporters/base.py +324 -0
  524. truthound/reporters/ci/__init__.py +66 -0
  525. truthound/reporters/ci/azure.py +436 -0
  526. truthound/reporters/ci/base.py +509 -0
  527. truthound/reporters/ci/bitbucket.py +567 -0
  528. truthound/reporters/ci/circleci.py +547 -0
  529. truthound/reporters/ci/detection.py +364 -0
  530. truthound/reporters/ci/factory.py +182 -0
  531. truthound/reporters/ci/github.py +388 -0
  532. truthound/reporters/ci/gitlab.py +471 -0
  533. truthound/reporters/ci/jenkins.py +525 -0
  534. truthound/reporters/console_reporter.py +299 -0
  535. truthound/reporters/factory.py +211 -0
  536. truthound/reporters/html_reporter.py +524 -0
  537. truthound/reporters/json_reporter.py +256 -0
  538. truthound/reporters/markdown_reporter.py +280 -0
  539. truthound/reporters/sdk/__init__.py +174 -0
  540. truthound/reporters/sdk/builder.py +558 -0
  541. truthound/reporters/sdk/mixins.py +1150 -0
  542. truthound/reporters/sdk/schema.py +1493 -0
  543. truthound/reporters/sdk/templates.py +666 -0
  544. truthound/reporters/sdk/testing.py +968 -0
  545. truthound/scanners.py +170 -0
  546. truthound/scheduling/__init__.py +122 -0
  547. truthound/scheduling/cron.py +1136 -0
  548. truthound/scheduling/presets.py +212 -0
  549. truthound/schema.py +275 -0
  550. truthound/secrets/__init__.py +173 -0
  551. truthound/secrets/base.py +618 -0
  552. truthound/secrets/cloud.py +682 -0
  553. truthound/secrets/integration.py +507 -0
  554. truthound/secrets/manager.py +633 -0
  555. truthound/secrets/oidc/__init__.py +172 -0
  556. truthound/secrets/oidc/base.py +902 -0
  557. truthound/secrets/oidc/credential_provider.py +623 -0
  558. truthound/secrets/oidc/exchangers.py +1001 -0
  559. truthound/secrets/oidc/github/__init__.py +110 -0
  560. truthound/secrets/oidc/github/claims.py +718 -0
  561. truthound/secrets/oidc/github/enhanced_provider.py +693 -0
  562. truthound/secrets/oidc/github/trust_policy.py +742 -0
  563. truthound/secrets/oidc/github/verification.py +723 -0
  564. truthound/secrets/oidc/github/workflow.py +691 -0
  565. truthound/secrets/oidc/providers.py +825 -0
  566. truthound/secrets/providers.py +506 -0
  567. truthound/secrets/resolver.py +495 -0
  568. truthound/stores/__init__.py +177 -0
  569. truthound/stores/backends/__init__.py +18 -0
  570. truthound/stores/backends/_protocols.py +340 -0
  571. truthound/stores/backends/azure_blob.py +530 -0
  572. truthound/stores/backends/concurrent_filesystem.py +915 -0
  573. truthound/stores/backends/connection_pool.py +1365 -0
  574. truthound/stores/backends/database.py +743 -0
  575. truthound/stores/backends/filesystem.py +538 -0
  576. truthound/stores/backends/gcs.py +399 -0
  577. truthound/stores/backends/memory.py +354 -0
  578. truthound/stores/backends/s3.py +434 -0
  579. truthound/stores/backpressure/__init__.py +84 -0
  580. truthound/stores/backpressure/base.py +375 -0
  581. truthound/stores/backpressure/circuit_breaker.py +434 -0
  582. truthound/stores/backpressure/monitor.py +376 -0
  583. truthound/stores/backpressure/strategies.py +677 -0
  584. truthound/stores/base.py +551 -0
  585. truthound/stores/batching/__init__.py +65 -0
  586. truthound/stores/batching/base.py +305 -0
  587. truthound/stores/batching/buffer.py +370 -0
  588. truthound/stores/batching/store.py +248 -0
  589. truthound/stores/batching/writer.py +521 -0
  590. truthound/stores/caching/__init__.py +60 -0
  591. truthound/stores/caching/backends.py +684 -0
  592. truthound/stores/caching/base.py +356 -0
  593. truthound/stores/caching/store.py +305 -0
  594. truthound/stores/compression/__init__.py +193 -0
  595. truthound/stores/compression/adaptive.py +694 -0
  596. truthound/stores/compression/base.py +514 -0
  597. truthound/stores/compression/pipeline.py +868 -0
  598. truthound/stores/compression/providers.py +672 -0
  599. truthound/stores/compression/streaming.py +832 -0
  600. truthound/stores/concurrency/__init__.py +81 -0
  601. truthound/stores/concurrency/atomic.py +556 -0
  602. truthound/stores/concurrency/index.py +775 -0
  603. truthound/stores/concurrency/locks.py +576 -0
  604. truthound/stores/concurrency/manager.py +482 -0
  605. truthound/stores/encryption/__init__.py +297 -0
  606. truthound/stores/encryption/base.py +952 -0
  607. truthound/stores/encryption/keys.py +1191 -0
  608. truthound/stores/encryption/pipeline.py +903 -0
  609. truthound/stores/encryption/providers.py +953 -0
  610. truthound/stores/encryption/streaming.py +950 -0
  611. truthound/stores/expectations.py +227 -0
  612. truthound/stores/factory.py +246 -0
  613. truthound/stores/migration/__init__.py +75 -0
  614. truthound/stores/migration/base.py +480 -0
  615. truthound/stores/migration/manager.py +347 -0
  616. truthound/stores/migration/registry.py +382 -0
  617. truthound/stores/migration/store.py +559 -0
  618. truthound/stores/observability/__init__.py +106 -0
  619. truthound/stores/observability/audit.py +718 -0
  620. truthound/stores/observability/config.py +270 -0
  621. truthound/stores/observability/factory.py +208 -0
  622. truthound/stores/observability/metrics.py +636 -0
  623. truthound/stores/observability/protocols.py +410 -0
  624. truthound/stores/observability/store.py +570 -0
  625. truthound/stores/observability/tracing.py +784 -0
  626. truthound/stores/replication/__init__.py +76 -0
  627. truthound/stores/replication/base.py +260 -0
  628. truthound/stores/replication/monitor.py +269 -0
  629. truthound/stores/replication/store.py +439 -0
  630. truthound/stores/replication/syncer.py +391 -0
  631. truthound/stores/results.py +359 -0
  632. truthound/stores/retention/__init__.py +77 -0
  633. truthound/stores/retention/base.py +378 -0
  634. truthound/stores/retention/policies.py +621 -0
  635. truthound/stores/retention/scheduler.py +279 -0
  636. truthound/stores/retention/store.py +526 -0
  637. truthound/stores/streaming/__init__.py +138 -0
  638. truthound/stores/streaming/base.py +801 -0
  639. truthound/stores/streaming/database.py +984 -0
  640. truthound/stores/streaming/filesystem.py +719 -0
  641. truthound/stores/streaming/reader.py +629 -0
  642. truthound/stores/streaming/s3.py +843 -0
  643. truthound/stores/streaming/writer.py +790 -0
  644. truthound/stores/tiering/__init__.py +108 -0
  645. truthound/stores/tiering/base.py +462 -0
  646. truthound/stores/tiering/manager.py +249 -0
  647. truthound/stores/tiering/policies.py +692 -0
  648. truthound/stores/tiering/store.py +526 -0
  649. truthound/stores/versioning/__init__.py +56 -0
  650. truthound/stores/versioning/base.py +376 -0
  651. truthound/stores/versioning/store.py +660 -0
  652. truthound/stores/versioning/strategies.py +353 -0
  653. truthound/types.py +56 -0
  654. truthound/validators/__init__.py +774 -0
  655. truthound/validators/aggregate/__init__.py +27 -0
  656. truthound/validators/aggregate/central.py +116 -0
  657. truthound/validators/aggregate/extremes.py +116 -0
  658. truthound/validators/aggregate/spread.py +118 -0
  659. truthound/validators/aggregate/sum.py +64 -0
  660. truthound/validators/aggregate/type.py +78 -0
  661. truthound/validators/anomaly/__init__.py +93 -0
  662. truthound/validators/anomaly/base.py +431 -0
  663. truthound/validators/anomaly/ml_based.py +1190 -0
  664. truthound/validators/anomaly/multivariate.py +647 -0
  665. truthound/validators/anomaly/statistical.py +599 -0
  666. truthound/validators/base.py +1089 -0
  667. truthound/validators/business_rule/__init__.py +46 -0
  668. truthound/validators/business_rule/base.py +147 -0
  669. truthound/validators/business_rule/checksum.py +509 -0
  670. truthound/validators/business_rule/financial.py +526 -0
  671. truthound/validators/cache.py +733 -0
  672. truthound/validators/completeness/__init__.py +39 -0
  673. truthound/validators/completeness/conditional.py +73 -0
  674. truthound/validators/completeness/default.py +98 -0
  675. truthound/validators/completeness/empty.py +103 -0
  676. truthound/validators/completeness/nan.py +337 -0
  677. truthound/validators/completeness/null.py +152 -0
  678. truthound/validators/cross_table/__init__.py +17 -0
  679. truthound/validators/cross_table/aggregate.py +333 -0
  680. truthound/validators/cross_table/row_count.py +122 -0
  681. truthound/validators/datetime/__init__.py +29 -0
  682. truthound/validators/datetime/format.py +78 -0
  683. truthound/validators/datetime/freshness.py +269 -0
  684. truthound/validators/datetime/order.py +73 -0
  685. truthound/validators/datetime/parseable.py +185 -0
  686. truthound/validators/datetime/range.py +202 -0
  687. truthound/validators/datetime/timezone.py +69 -0
  688. truthound/validators/distribution/__init__.py +49 -0
  689. truthound/validators/distribution/distribution.py +128 -0
  690. truthound/validators/distribution/monotonic.py +119 -0
  691. truthound/validators/distribution/outlier.py +178 -0
  692. truthound/validators/distribution/quantile.py +80 -0
  693. truthound/validators/distribution/range.py +254 -0
  694. truthound/validators/distribution/set.py +125 -0
  695. truthound/validators/distribution/statistical.py +459 -0
  696. truthound/validators/drift/__init__.py +79 -0
  697. truthound/validators/drift/base.py +427 -0
  698. truthound/validators/drift/multi_feature.py +401 -0
  699. truthound/validators/drift/numeric.py +395 -0
  700. truthound/validators/drift/psi.py +446 -0
  701. truthound/validators/drift/statistical.py +510 -0
  702. truthound/validators/enterprise.py +1658 -0
  703. truthound/validators/geospatial/__init__.py +80 -0
  704. truthound/validators/geospatial/base.py +97 -0
  705. truthound/validators/geospatial/boundary.py +238 -0
  706. truthound/validators/geospatial/coordinate.py +351 -0
  707. truthound/validators/geospatial/distance.py +399 -0
  708. truthound/validators/geospatial/polygon.py +665 -0
  709. truthound/validators/i18n/__init__.py +308 -0
  710. truthound/validators/i18n/bidi.py +571 -0
  711. truthound/validators/i18n/catalogs.py +570 -0
  712. truthound/validators/i18n/dialects.py +763 -0
  713. truthound/validators/i18n/extended_catalogs.py +549 -0
  714. truthound/validators/i18n/formatting.py +1434 -0
  715. truthound/validators/i18n/loader.py +1020 -0
  716. truthound/validators/i18n/messages.py +521 -0
  717. truthound/validators/i18n/plural.py +683 -0
  718. truthound/validators/i18n/protocols.py +855 -0
  719. truthound/validators/i18n/tms.py +1162 -0
  720. truthound/validators/localization/__init__.py +53 -0
  721. truthound/validators/localization/base.py +122 -0
  722. truthound/validators/localization/chinese.py +362 -0
  723. truthound/validators/localization/japanese.py +275 -0
  724. truthound/validators/localization/korean.py +524 -0
  725. truthound/validators/memory/__init__.py +94 -0
  726. truthound/validators/memory/approximate_knn.py +506 -0
  727. truthound/validators/memory/base.py +547 -0
  728. truthound/validators/memory/sgd_online.py +719 -0
  729. truthound/validators/memory/streaming_ecdf.py +753 -0
  730. truthound/validators/ml_feature/__init__.py +54 -0
  731. truthound/validators/ml_feature/base.py +249 -0
  732. truthound/validators/ml_feature/correlation.py +299 -0
  733. truthound/validators/ml_feature/leakage.py +344 -0
  734. truthound/validators/ml_feature/null_impact.py +270 -0
  735. truthound/validators/ml_feature/scale.py +264 -0
  736. truthound/validators/multi_column/__init__.py +89 -0
  737. truthound/validators/multi_column/arithmetic.py +284 -0
  738. truthound/validators/multi_column/base.py +231 -0
  739. truthound/validators/multi_column/comparison.py +273 -0
  740. truthound/validators/multi_column/consistency.py +312 -0
  741. truthound/validators/multi_column/statistical.py +299 -0
  742. truthound/validators/optimization/__init__.py +164 -0
  743. truthound/validators/optimization/aggregation.py +563 -0
  744. truthound/validators/optimization/covariance.py +556 -0
  745. truthound/validators/optimization/geo.py +626 -0
  746. truthound/validators/optimization/graph.py +587 -0
  747. truthound/validators/optimization/orchestrator.py +970 -0
  748. truthound/validators/optimization/profiling.py +1312 -0
  749. truthound/validators/privacy/__init__.py +223 -0
  750. truthound/validators/privacy/base.py +635 -0
  751. truthound/validators/privacy/ccpa.py +670 -0
  752. truthound/validators/privacy/gdpr.py +728 -0
  753. truthound/validators/privacy/global_patterns.py +604 -0
  754. truthound/validators/privacy/plugins.py +867 -0
  755. truthound/validators/profiling/__init__.py +52 -0
  756. truthound/validators/profiling/base.py +175 -0
  757. truthound/validators/profiling/cardinality.py +312 -0
  758. truthound/validators/profiling/entropy.py +391 -0
  759. truthound/validators/profiling/frequency.py +455 -0
  760. truthound/validators/pushdown_support.py +660 -0
  761. truthound/validators/query/__init__.py +91 -0
  762. truthound/validators/query/aggregate.py +346 -0
  763. truthound/validators/query/base.py +246 -0
  764. truthound/validators/query/column.py +249 -0
  765. truthound/validators/query/expression.py +274 -0
  766. truthound/validators/query/result.py +323 -0
  767. truthound/validators/query/row_count.py +264 -0
  768. truthound/validators/referential/__init__.py +80 -0
  769. truthound/validators/referential/base.py +395 -0
  770. truthound/validators/referential/cascade.py +391 -0
  771. truthound/validators/referential/circular.py +563 -0
  772. truthound/validators/referential/foreign_key.py +624 -0
  773. truthound/validators/referential/orphan.py +485 -0
  774. truthound/validators/registry.py +112 -0
  775. truthound/validators/schema/__init__.py +41 -0
  776. truthound/validators/schema/column_count.py +142 -0
  777. truthound/validators/schema/column_exists.py +80 -0
  778. truthound/validators/schema/column_order.py +82 -0
  779. truthound/validators/schema/column_pair.py +85 -0
  780. truthound/validators/schema/column_pair_set.py +195 -0
  781. truthound/validators/schema/column_type.py +94 -0
  782. truthound/validators/schema/multi_column.py +53 -0
  783. truthound/validators/schema/multi_column_aggregate.py +175 -0
  784. truthound/validators/schema/referential.py +274 -0
  785. truthound/validators/schema/table_schema.py +91 -0
  786. truthound/validators/schema_validator.py +219 -0
  787. truthound/validators/sdk/__init__.py +250 -0
  788. truthound/validators/sdk/builder.py +680 -0
  789. truthound/validators/sdk/decorators.py +474 -0
  790. truthound/validators/sdk/enterprise/__init__.py +211 -0
  791. truthound/validators/sdk/enterprise/docs.py +725 -0
  792. truthound/validators/sdk/enterprise/fuzzing.py +659 -0
  793. truthound/validators/sdk/enterprise/licensing.py +709 -0
  794. truthound/validators/sdk/enterprise/manager.py +543 -0
  795. truthound/validators/sdk/enterprise/resources.py +628 -0
  796. truthound/validators/sdk/enterprise/sandbox.py +766 -0
  797. truthound/validators/sdk/enterprise/signing.py +603 -0
  798. truthound/validators/sdk/enterprise/templates.py +865 -0
  799. truthound/validators/sdk/enterprise/versioning.py +659 -0
  800. truthound/validators/sdk/templates.py +757 -0
  801. truthound/validators/sdk/testing.py +807 -0
  802. truthound/validators/security/__init__.py +181 -0
  803. truthound/validators/security/redos/__init__.py +182 -0
  804. truthound/validators/security/redos/core.py +861 -0
  805. truthound/validators/security/redos/cpu_monitor.py +593 -0
  806. truthound/validators/security/redos/cve_database.py +791 -0
  807. truthound/validators/security/redos/ml/__init__.py +155 -0
  808. truthound/validators/security/redos/ml/base.py +785 -0
  809. truthound/validators/security/redos/ml/datasets.py +618 -0
  810. truthound/validators/security/redos/ml/features.py +359 -0
  811. truthound/validators/security/redos/ml/models.py +1000 -0
  812. truthound/validators/security/redos/ml/predictor.py +507 -0
  813. truthound/validators/security/redos/ml/storage.py +632 -0
  814. truthound/validators/security/redos/ml/training.py +571 -0
  815. truthound/validators/security/redos/ml_analyzer.py +937 -0
  816. truthound/validators/security/redos/optimizer.py +674 -0
  817. truthound/validators/security/redos/profiler.py +682 -0
  818. truthound/validators/security/redos/re2_engine.py +709 -0
  819. truthound/validators/security/redos.py +886 -0
  820. truthound/validators/security/sql_security.py +1247 -0
  821. truthound/validators/streaming/__init__.py +126 -0
  822. truthound/validators/streaming/base.py +292 -0
  823. truthound/validators/streaming/completeness.py +210 -0
  824. truthound/validators/streaming/mixin.py +575 -0
  825. truthound/validators/streaming/range.py +308 -0
  826. truthound/validators/streaming/sources.py +846 -0
  827. truthound/validators/string/__init__.py +57 -0
  828. truthound/validators/string/casing.py +158 -0
  829. truthound/validators/string/charset.py +96 -0
  830. truthound/validators/string/format.py +501 -0
  831. truthound/validators/string/json.py +77 -0
  832. truthound/validators/string/json_schema.py +184 -0
  833. truthound/validators/string/length.py +104 -0
  834. truthound/validators/string/like_pattern.py +237 -0
  835. truthound/validators/string/regex.py +202 -0
  836. truthound/validators/string/regex_extended.py +435 -0
  837. truthound/validators/table/__init__.py +88 -0
  838. truthound/validators/table/base.py +78 -0
  839. truthound/validators/table/column_count.py +198 -0
  840. truthound/validators/table/freshness.py +362 -0
  841. truthound/validators/table/row_count.py +251 -0
  842. truthound/validators/table/schema.py +333 -0
  843. truthound/validators/table/size.py +285 -0
  844. truthound/validators/timeout/__init__.py +102 -0
  845. truthound/validators/timeout/advanced/__init__.py +247 -0
  846. truthound/validators/timeout/advanced/circuit_breaker.py +675 -0
  847. truthound/validators/timeout/advanced/prediction.py +773 -0
  848. truthound/validators/timeout/advanced/priority.py +618 -0
  849. truthound/validators/timeout/advanced/redis_backend.py +770 -0
  850. truthound/validators/timeout/advanced/retry.py +721 -0
  851. truthound/validators/timeout/advanced/sampling.py +788 -0
  852. truthound/validators/timeout/advanced/sla.py +661 -0
  853. truthound/validators/timeout/advanced/telemetry.py +804 -0
  854. truthound/validators/timeout/cascade.py +477 -0
  855. truthound/validators/timeout/deadline.py +657 -0
  856. truthound/validators/timeout/degradation.py +525 -0
  857. truthound/validators/timeout/distributed.py +597 -0
  858. truthound/validators/timeseries/__init__.py +89 -0
  859. truthound/validators/timeseries/base.py +326 -0
  860. truthound/validators/timeseries/completeness.py +617 -0
  861. truthound/validators/timeseries/gap.py +485 -0
  862. truthound/validators/timeseries/monotonic.py +310 -0
  863. truthound/validators/timeseries/seasonality.py +422 -0
  864. truthound/validators/timeseries/trend.py +510 -0
  865. truthound/validators/uniqueness/__init__.py +59 -0
  866. truthound/validators/uniqueness/approximate.py +475 -0
  867. truthound/validators/uniqueness/distinct_values.py +253 -0
  868. truthound/validators/uniqueness/duplicate.py +118 -0
  869. truthound/validators/uniqueness/primary_key.py +140 -0
  870. truthound/validators/uniqueness/unique.py +191 -0
  871. truthound/validators/uniqueness/within_record.py +599 -0
  872. truthound/validators/utils.py +756 -0
  873. truthound-1.0.8.dist-info/METADATA +474 -0
  874. truthound-1.0.8.dist-info/RECORD +877 -0
  875. truthound-1.0.8.dist-info/WHEEL +4 -0
  876. truthound-1.0.8.dist-info/entry_points.txt +2 -0
  877. truthound-1.0.8.dist-info/licenses/LICENSE +190 -0
@@ -0,0 +1,842 @@
1
+ """Protocols and Data Classes for Distributed Checkpoint Orchestration.
2
+
3
+ This module defines the core abstractions for distributed checkpoint execution,
4
+ including backend protocols, task states, and configuration options.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import logging
10
+ from abc import abstractmethod
11
+ from dataclasses import dataclass, field
12
+ from datetime import datetime, timedelta
13
+ from enum import Enum, Flag, auto
14
+ from typing import (
15
+ TYPE_CHECKING,
16
+ Any,
17
+ AsyncIterator,
18
+ Callable,
19
+ Generator,
20
+ Generic,
21
+ Iterator,
22
+ Protocol,
23
+ TypeVar,
24
+ runtime_checkable,
25
+ )
26
+ from uuid import uuid4
27
+
28
+ if TYPE_CHECKING:
29
+ from truthound.checkpoint.checkpoint import Checkpoint, CheckpointResult
30
+
31
+
32
+ logger = logging.getLogger(__name__)
33
+
34
+
35
+ # =============================================================================
36
+ # Exceptions
37
+ # =============================================================================
38
+
39
+
40
+ class DistributedError(Exception):
41
+ """Base exception for distributed checkpoint errors."""
42
+
43
+ def __init__(self, message: str, details: dict[str, Any] | None = None) -> None:
44
+ super().__init__(message)
45
+ self.message = message
46
+ self.details = details or {}
47
+
48
+
49
+ class TaskSubmissionError(DistributedError):
50
+ """Raised when task submission fails."""
51
+
52
+ def __init__(
53
+ self,
54
+ message: str,
55
+ checkpoint_name: str | None = None,
56
+ reason: str | None = None,
57
+ ) -> None:
58
+ super().__init__(message, {"checkpoint_name": checkpoint_name, "reason": reason})
59
+ self.checkpoint_name = checkpoint_name
60
+ self.reason = reason
61
+
62
+
63
+ class TaskTimeoutError(DistributedError):
64
+ """Raised when task execution times out."""
65
+
66
+ def __init__(
67
+ self,
68
+ message: str,
69
+ task_id: str,
70
+ timeout_seconds: float,
71
+ ) -> None:
72
+ super().__init__(message, {"task_id": task_id, "timeout_seconds": timeout_seconds})
73
+ self.task_id = task_id
74
+ self.timeout_seconds = timeout_seconds
75
+
76
+
77
+ class TaskCancelledError(DistributedError):
78
+ """Raised when task is cancelled."""
79
+
80
+ def __init__(self, message: str, task_id: str, reason: str | None = None) -> None:
81
+ super().__init__(message, {"task_id": task_id, "reason": reason})
82
+ self.task_id = task_id
83
+ self.reason = reason
84
+
85
+
86
+ class WorkerNotAvailableError(DistributedError):
87
+ """Raised when no workers are available."""
88
+
89
+ def __init__(
90
+ self,
91
+ message: str = "No workers available",
92
+ required_workers: int = 1,
93
+ available_workers: int = 0,
94
+ ) -> None:
95
+ super().__init__(
96
+ message,
97
+ {"required_workers": required_workers, "available_workers": available_workers},
98
+ )
99
+ self.required_workers = required_workers
100
+ self.available_workers = available_workers
101
+
102
+
103
+ class BackendNotAvailableError(DistributedError):
104
+ """Raised when backend is not available."""
105
+
106
+ def __init__(
107
+ self,
108
+ backend_name: str,
109
+ reason: str | None = None,
110
+ install_hint: str | None = None,
111
+ ) -> None:
112
+ message = f"Backend '{backend_name}' is not available"
113
+ if reason:
114
+ message += f": {reason}"
115
+ super().__init__(message, {"backend_name": backend_name, "install_hint": install_hint})
116
+ self.backend_name = backend_name
117
+ self.reason = reason
118
+ self.install_hint = install_hint
119
+
120
+
121
+ # =============================================================================
122
+ # Enums
123
+ # =============================================================================
124
+
125
+
126
+ class TaskState(str, Enum):
127
+ """State of a distributed task."""
128
+
129
+ PENDING = "pending" # Task created but not yet submitted
130
+ SUBMITTED = "submitted" # Task submitted to backend
131
+ QUEUED = "queued" # Task in backend queue
132
+ RUNNING = "running" # Task currently executing
133
+ SUCCEEDED = "succeeded" # Task completed successfully
134
+ FAILED = "failed" # Task failed with error
135
+ CANCELLED = "cancelled" # Task was cancelled
136
+ REVOKED = "revoked" # Task was revoked (Celery term)
137
+ RETRYING = "retrying" # Task is being retried
138
+ TIMEOUT = "timeout" # Task timed out
139
+
140
+ @property
141
+ def is_terminal(self) -> bool:
142
+ """Check if state is terminal (no further transitions)."""
143
+ return self in {
144
+ TaskState.SUCCEEDED,
145
+ TaskState.FAILED,
146
+ TaskState.CANCELLED,
147
+ TaskState.REVOKED,
148
+ TaskState.TIMEOUT,
149
+ }
150
+
151
+ @property
152
+ def is_active(self) -> bool:
153
+ """Check if task is actively processing."""
154
+ return self in {TaskState.RUNNING, TaskState.RETRYING}
155
+
156
+
157
+ class TaskPriority(int, Enum):
158
+ """Priority levels for task scheduling."""
159
+
160
+ LOWEST = 0
161
+ LOW = 3
162
+ NORMAL = 5
163
+ HIGH = 7
164
+ HIGHEST = 9
165
+ CRITICAL = 10
166
+
167
+ @classmethod
168
+ def from_int(cls, value: int) -> "TaskPriority":
169
+ """Convert integer to priority."""
170
+ if value <= 0:
171
+ return cls.LOWEST
172
+ elif value <= 3:
173
+ return cls.LOW
174
+ elif value <= 5:
175
+ return cls.NORMAL
176
+ elif value <= 7:
177
+ return cls.HIGH
178
+ elif value <= 9:
179
+ return cls.HIGHEST
180
+ return cls.CRITICAL
181
+
182
+
183
+ class WorkerState(str, Enum):
184
+ """State of a worker node."""
185
+
186
+ ONLINE = "online" # Worker is online and accepting tasks
187
+ OFFLINE = "offline" # Worker is offline
188
+ BUSY = "busy" # Worker is at capacity
189
+ DRAINING = "draining" # Worker is draining (no new tasks)
190
+ MAINTENANCE = "maintenance" # Worker is in maintenance mode
191
+ UNKNOWN = "unknown" # Worker state unknown
192
+
193
+
194
+ class BackendCapability(Flag):
195
+ """Capabilities supported by a backend."""
196
+
197
+ NONE = 0
198
+ ASYNC_SUBMIT = auto() # Async task submission
199
+ BATCH_SUBMIT = auto() # Batch task submission
200
+ PRIORITY_QUEUE = auto() # Priority-based scheduling
201
+ RETRY_POLICY = auto() # Automatic retry on failure
202
+ RATE_LIMITING = auto() # Task rate limiting
203
+ TASK_ROUTING = auto() # Route tasks to specific workers
204
+ RESULT_BACKEND = auto() # Store task results
205
+ TASK_REVOKE = auto() # Revoke/cancel running tasks
206
+ PROGRESS_TRACKING = auto() # Track task progress
207
+ CHAIN_TASKS = auto() # Chain tasks together
208
+ GROUP_TASKS = auto() # Execute tasks in groups
209
+ BROADCAST = auto() # Broadcast to all workers
210
+ SCHEDULED_TASKS = auto() # Schedule tasks for later execution
211
+ WORKER_SCALING = auto() # Dynamic worker scaling
212
+ HEALTH_CHECK = auto() # Worker health checks
213
+ METRICS = auto() # Collect execution metrics
214
+
215
+ # Common capability sets
216
+ BASIC = ASYNC_SUBMIT | RESULT_BACKEND
217
+ STANDARD = BASIC | BATCH_SUBMIT | RETRY_POLICY | TASK_REVOKE
218
+ ADVANCED = STANDARD | PRIORITY_QUEUE | PROGRESS_TRACKING | CHAIN_TASKS | GROUP_TASKS
219
+ FULL = ADVANCED | RATE_LIMITING | TASK_ROUTING | BROADCAST | SCHEDULED_TASKS | WORKER_SCALING | HEALTH_CHECK | METRICS
220
+
221
+
222
+ # =============================================================================
223
+ # Data Classes
224
+ # =============================================================================
225
+
226
+
227
+ @dataclass
228
+ class DistributedConfig:
229
+ """Configuration for distributed checkpoint orchestration.
230
+
231
+ Attributes:
232
+ backend: Backend type ("celery", "ray", "kubernetes", "local").
233
+ max_workers: Maximum number of concurrent workers.
234
+ max_retries: Maximum retry attempts on failure.
235
+ retry_delay_seconds: Delay between retries.
236
+ task_timeout_seconds: Default task timeout.
237
+ result_ttl_seconds: How long to keep results.
238
+ heartbeat_interval_seconds: Worker heartbeat interval.
239
+ enable_metrics: Enable metrics collection.
240
+ enable_tracing: Enable distributed tracing.
241
+ backend_options: Backend-specific configuration.
242
+ """
243
+
244
+ backend: str = "local"
245
+ max_workers: int = 4
246
+ max_retries: int = 3
247
+ retry_delay_seconds: float = 5.0
248
+ retry_backoff_multiplier: float = 2.0
249
+ retry_max_delay_seconds: float = 300.0
250
+ task_timeout_seconds: float = 3600.0
251
+ result_ttl_seconds: float = 86400.0 # 24 hours
252
+ heartbeat_interval_seconds: float = 30.0
253
+ enable_metrics: bool = True
254
+ enable_tracing: bool = False
255
+ backend_options: dict[str, Any] = field(default_factory=dict)
256
+
257
+ def with_backend(self, backend: str, **options: Any) -> "DistributedConfig":
258
+ """Create new config with different backend."""
259
+ new_options = {**self.backend_options, **options}
260
+ return DistributedConfig(
261
+ backend=backend,
262
+ max_workers=self.max_workers,
263
+ max_retries=self.max_retries,
264
+ retry_delay_seconds=self.retry_delay_seconds,
265
+ retry_backoff_multiplier=self.retry_backoff_multiplier,
266
+ retry_max_delay_seconds=self.retry_max_delay_seconds,
267
+ task_timeout_seconds=self.task_timeout_seconds,
268
+ result_ttl_seconds=self.result_ttl_seconds,
269
+ heartbeat_interval_seconds=self.heartbeat_interval_seconds,
270
+ enable_metrics=self.enable_metrics,
271
+ enable_tracing=self.enable_tracing,
272
+ backend_options=new_options,
273
+ )
274
+
275
+
276
+ @dataclass
277
+ class WorkerInfo:
278
+ """Information about a worker node.
279
+
280
+ Attributes:
281
+ worker_id: Unique worker identifier.
282
+ hostname: Worker hostname.
283
+ state: Current worker state.
284
+ current_tasks: Number of tasks currently running.
285
+ max_concurrency: Maximum concurrent tasks.
286
+ registered_at: When worker registered.
287
+ last_heartbeat: Last heartbeat timestamp.
288
+ tags: Worker tags for routing.
289
+ metadata: Additional worker metadata.
290
+ """
291
+
292
+ worker_id: str
293
+ hostname: str
294
+ state: WorkerState = WorkerState.UNKNOWN
295
+ current_tasks: int = 0
296
+ max_concurrency: int = 1
297
+ registered_at: datetime = field(default_factory=datetime.now)
298
+ last_heartbeat: datetime = field(default_factory=datetime.now)
299
+ tags: set[str] = field(default_factory=set)
300
+ metadata: dict[str, Any] = field(default_factory=dict)
301
+
302
+ @property
303
+ def is_available(self) -> bool:
304
+ """Check if worker can accept new tasks."""
305
+ return (
306
+ self.state == WorkerState.ONLINE
307
+ and self.current_tasks < self.max_concurrency
308
+ )
309
+
310
+ @property
311
+ def available_slots(self) -> int:
312
+ """Get number of available task slots."""
313
+ if self.state != WorkerState.ONLINE:
314
+ return 0
315
+ return max(0, self.max_concurrency - self.current_tasks)
316
+
317
+ @property
318
+ def load_factor(self) -> float:
319
+ """Get worker load factor (0.0 to 1.0)."""
320
+ if self.max_concurrency == 0:
321
+ return 1.0
322
+ return self.current_tasks / self.max_concurrency
323
+
324
+
325
+ @dataclass
326
+ class ClusterState:
327
+ """State of the distributed cluster.
328
+
329
+ Attributes:
330
+ workers: List of worker info.
331
+ total_capacity: Total task capacity.
332
+ current_load: Current number of running tasks.
333
+ pending_tasks: Number of pending tasks.
334
+ backend_name: Name of the backend.
335
+ backend_version: Version of the backend.
336
+ is_healthy: Whether cluster is healthy.
337
+ last_updated: When state was last updated.
338
+ """
339
+
340
+ workers: list[WorkerInfo] = field(default_factory=list)
341
+ total_capacity: int = 0
342
+ current_load: int = 0
343
+ pending_tasks: int = 0
344
+ backend_name: str = ""
345
+ backend_version: str = ""
346
+ is_healthy: bool = True
347
+ last_updated: datetime = field(default_factory=datetime.now)
348
+
349
+ @property
350
+ def available_capacity(self) -> int:
351
+ """Get available capacity."""
352
+ return self.total_capacity - self.current_load
353
+
354
+ @property
355
+ def online_workers(self) -> list[WorkerInfo]:
356
+ """Get list of online workers."""
357
+ return [w for w in self.workers if w.state == WorkerState.ONLINE]
358
+
359
+ @property
360
+ def utilization(self) -> float:
361
+ """Get cluster utilization (0.0 to 1.0)."""
362
+ if self.total_capacity == 0:
363
+ return 0.0
364
+ return self.current_load / self.total_capacity
365
+
366
+
367
+ @dataclass
368
+ class DistributedTaskResult:
369
+ """Result of a distributed task execution.
370
+
371
+ Attributes:
372
+ task_id: Unique task identifier.
373
+ checkpoint_name: Name of the checkpoint that was run.
374
+ state: Final task state.
375
+ result: The CheckpointResult if successful.
376
+ error: Error message if failed.
377
+ exception: Exception if failed.
378
+ worker_id: ID of worker that executed the task.
379
+ submitted_at: When task was submitted.
380
+ started_at: When task started executing.
381
+ completed_at: When task completed.
382
+ retries: Number of retry attempts.
383
+ metadata: Additional result metadata.
384
+ """
385
+
386
+ task_id: str
387
+ checkpoint_name: str
388
+ state: TaskState
389
+ result: "CheckpointResult | None" = None
390
+ error: str | None = None
391
+ exception: Exception | None = None
392
+ worker_id: str | None = None
393
+ submitted_at: datetime | None = None
394
+ started_at: datetime | None = None
395
+ completed_at: datetime | None = None
396
+ retries: int = 0
397
+ metadata: dict[str, Any] = field(default_factory=dict)
398
+
399
+ @property
400
+ def success(self) -> bool:
401
+ """Check if task succeeded."""
402
+ return self.state == TaskState.SUCCEEDED
403
+
404
+ @property
405
+ def duration_ms(self) -> float | None:
406
+ """Get execution duration in milliseconds."""
407
+ if self.started_at and self.completed_at:
408
+ return (self.completed_at - self.started_at).total_seconds() * 1000
409
+ return None
410
+
411
+ @property
412
+ def queue_time_ms(self) -> float | None:
413
+ """Get time spent in queue in milliseconds."""
414
+ if self.submitted_at and self.started_at:
415
+ return (self.started_at - self.submitted_at).total_seconds() * 1000
416
+ return None
417
+
418
+ def to_dict(self) -> dict[str, Any]:
419
+ """Convert to dictionary."""
420
+ return {
421
+ "task_id": self.task_id,
422
+ "checkpoint_name": self.checkpoint_name,
423
+ "state": self.state.value,
424
+ "result": self.result.to_dict() if self.result else None,
425
+ "error": self.error,
426
+ "worker_id": self.worker_id,
427
+ "submitted_at": self.submitted_at.isoformat() if self.submitted_at else None,
428
+ "started_at": self.started_at.isoformat() if self.started_at else None,
429
+ "completed_at": self.completed_at.isoformat() if self.completed_at else None,
430
+ "retries": self.retries,
431
+ "duration_ms": self.duration_ms,
432
+ "queue_time_ms": self.queue_time_ms,
433
+ "metadata": self.metadata,
434
+ }
435
+
436
+
437
+ # =============================================================================
438
+ # Protocols
439
+ # =============================================================================
440
+
441
+
442
+ T = TypeVar("T")
443
+
444
+
445
+ @runtime_checkable
446
+ class DistributedTaskProtocol(Protocol[T]):
447
+ """Protocol for a distributed task handle.
448
+
449
+ This represents a submitted task that can be awaited, cancelled, or queried.
450
+ """
451
+
452
+ @property
453
+ def task_id(self) -> str:
454
+ """Get unique task identifier."""
455
+ ...
456
+
457
+ @property
458
+ def state(self) -> TaskState:
459
+ """Get current task state."""
460
+ ...
461
+
462
+ @property
463
+ def checkpoint_name(self) -> str:
464
+ """Get name of the checkpoint being executed."""
465
+ ...
466
+
467
+ def result(self, timeout: float | None = None) -> T:
468
+ """Wait for and return the task result.
469
+
470
+ Args:
471
+ timeout: Maximum time to wait in seconds.
472
+
473
+ Returns:
474
+ Task result.
475
+
476
+ Raises:
477
+ TaskTimeoutError: If timeout exceeded.
478
+ TaskCancelledError: If task was cancelled.
479
+ DistributedError: If task failed.
480
+ """
481
+ ...
482
+
483
+ async def result_async(self, timeout: float | None = None) -> T:
484
+ """Async version of result().
485
+
486
+ Args:
487
+ timeout: Maximum time to wait in seconds.
488
+
489
+ Returns:
490
+ Task result.
491
+ """
492
+ ...
493
+
494
+ def cancel(self, terminate: bool = False) -> bool:
495
+ """Cancel the task.
496
+
497
+ Args:
498
+ terminate: If True, terminate even if running.
499
+
500
+ Returns:
501
+ True if cancelled, False if already completed.
502
+ """
503
+ ...
504
+
505
+ def is_ready(self) -> bool:
506
+ """Check if task has completed."""
507
+ ...
508
+
509
+ def is_successful(self) -> bool:
510
+ """Check if task completed successfully."""
511
+ ...
512
+
513
+ def wait(self, timeout: float | None = None) -> bool:
514
+ """Wait for task to complete.
515
+
516
+ Args:
517
+ timeout: Maximum time to wait.
518
+
519
+ Returns:
520
+ True if completed, False if timeout.
521
+ """
522
+ ...
523
+
524
+
525
+ @runtime_checkable
526
+ class DistributedBackendProtocol(Protocol):
527
+ """Protocol for distributed execution backends.
528
+
529
+ Implementations must provide methods for task submission, worker
530
+ management, and cluster state queries.
531
+ """
532
+
533
+ @property
534
+ def name(self) -> str:
535
+ """Get backend name."""
536
+ ...
537
+
538
+ @property
539
+ def capabilities(self) -> BackendCapability:
540
+ """Get backend capabilities."""
541
+ ...
542
+
543
+ @property
544
+ def is_connected(self) -> bool:
545
+ """Check if backend is connected."""
546
+ ...
547
+
548
+ def connect(self, **kwargs: Any) -> None:
549
+ """Connect to the backend.
550
+
551
+ Args:
552
+ **kwargs: Backend-specific connection options.
553
+
554
+ Raises:
555
+ BackendNotAvailableError: If connection fails.
556
+ """
557
+ ...
558
+
559
+ def disconnect(self) -> None:
560
+ """Disconnect from the backend."""
561
+ ...
562
+
563
+ def submit(
564
+ self,
565
+ checkpoint: "Checkpoint",
566
+ priority: TaskPriority = TaskPriority.NORMAL,
567
+ timeout: float | None = None,
568
+ context: dict[str, Any] | None = None,
569
+ **kwargs: Any,
570
+ ) -> DistributedTaskProtocol["CheckpointResult"]:
571
+ """Submit a checkpoint for execution.
572
+
573
+ Args:
574
+ checkpoint: Checkpoint to execute.
575
+ priority: Task priority.
576
+ timeout: Task timeout in seconds.
577
+ context: Additional context for the run.
578
+ **kwargs: Backend-specific options.
579
+
580
+ Returns:
581
+ Task handle for tracking execution.
582
+
583
+ Raises:
584
+ TaskSubmissionError: If submission fails.
585
+ """
586
+ ...
587
+
588
+ def submit_batch(
589
+ self,
590
+ checkpoints: list["Checkpoint"],
591
+ priority: TaskPriority = TaskPriority.NORMAL,
592
+ timeout: float | None = None,
593
+ context: dict[str, Any] | None = None,
594
+ **kwargs: Any,
595
+ ) -> list[DistributedTaskProtocol["CheckpointResult"]]:
596
+ """Submit multiple checkpoints for execution.
597
+
598
+ Args:
599
+ checkpoints: List of checkpoints to execute.
600
+ priority: Task priority.
601
+ timeout: Task timeout in seconds.
602
+ context: Additional context for all runs.
603
+ **kwargs: Backend-specific options.
604
+
605
+ Returns:
606
+ List of task handles.
607
+
608
+ Raises:
609
+ TaskSubmissionError: If submission fails.
610
+ """
611
+ ...
612
+
613
+ def get_task(self, task_id: str) -> DistributedTaskProtocol["CheckpointResult"] | None:
614
+ """Get a task by ID.
615
+
616
+ Args:
617
+ task_id: Task identifier.
618
+
619
+ Returns:
620
+ Task handle if found, None otherwise.
621
+ """
622
+ ...
623
+
624
+ def get_cluster_state(self) -> ClusterState:
625
+ """Get current cluster state.
626
+
627
+ Returns:
628
+ ClusterState with worker and capacity info.
629
+ """
630
+ ...
631
+
632
+ def get_workers(self) -> list[WorkerInfo]:
633
+ """Get list of workers.
634
+
635
+ Returns:
636
+ List of worker info.
637
+ """
638
+ ...
639
+
640
+ def scale_workers(self, count: int) -> bool:
641
+ """Scale the number of workers.
642
+
643
+ Args:
644
+ count: Desired worker count.
645
+
646
+ Returns:
647
+ True if scaling initiated, False if not supported.
648
+ """
649
+ ...
650
+
651
+ def health_check(self) -> bool:
652
+ """Perform health check.
653
+
654
+ Returns:
655
+ True if healthy, False otherwise.
656
+ """
657
+ ...
658
+
659
+
660
+ @dataclass
661
+ class DistributedTask(Generic[T]):
662
+ """Concrete implementation of a distributed task handle.
663
+
664
+ This provides a standard implementation that backends can use or extend.
665
+ """
666
+
667
+ task_id: str
668
+ checkpoint_name: str
669
+ _state: TaskState = TaskState.PENDING
670
+ _result: T | None = None
671
+ _error: str | None = None
672
+ _exception: Exception | None = None
673
+ _backend: Any = None # Reference to backend for operations
674
+ _submitted_at: datetime = field(default_factory=datetime.now)
675
+ _started_at: datetime | None = None
676
+ _completed_at: datetime | None = None
677
+ _worker_id: str | None = None
678
+ _retries: int = 0
679
+ _metadata: dict[str, Any] = field(default_factory=dict)
680
+ _callbacks: list[Callable[[T | None, Exception | None], None]] = field(
681
+ default_factory=list
682
+ )
683
+
684
+ @classmethod
685
+ def create(
686
+ cls,
687
+ checkpoint: "Checkpoint",
688
+ backend: Any = None,
689
+ ) -> "DistributedTask[T]":
690
+ """Create a new task for a checkpoint."""
691
+ return cls(
692
+ task_id=f"task-{uuid4().hex[:16]}",
693
+ checkpoint_name=checkpoint.name,
694
+ _state=TaskState.PENDING,
695
+ _backend=backend,
696
+ _submitted_at=datetime.now(),
697
+ )
698
+
699
+ @property
700
+ def state(self) -> TaskState:
701
+ """Get current task state."""
702
+ return self._state
703
+
704
+ def _set_state(self, state: TaskState) -> None:
705
+ """Set task state (internal use)."""
706
+ self._state = state
707
+
708
+ def _set_result(self, result: T) -> None:
709
+ """Set task result (internal use)."""
710
+ self._result = result
711
+ self._state = TaskState.SUCCEEDED
712
+ self._completed_at = datetime.now()
713
+ self._invoke_callbacks()
714
+
715
+ def _set_error(self, error: str, exception: Exception | None = None) -> None:
716
+ """Set task error (internal use)."""
717
+ self._error = error
718
+ self._exception = exception
719
+ self._state = TaskState.FAILED
720
+ self._completed_at = datetime.now()
721
+ self._invoke_callbacks()
722
+
723
+ def _invoke_callbacks(self) -> None:
724
+ """Invoke registered callbacks."""
725
+ for callback in self._callbacks:
726
+ try:
727
+ callback(self._result, self._exception)
728
+ except Exception as e:
729
+ logger.error(f"Callback error: {e}")
730
+
731
+ def result(self, timeout: float | None = None) -> T:
732
+ """Wait for and return the task result."""
733
+ import time
734
+
735
+ start = time.time()
736
+ while not self.is_ready():
737
+ if timeout and (time.time() - start) > timeout:
738
+ raise TaskTimeoutError(
739
+ f"Task {self.task_id} timed out",
740
+ self.task_id,
741
+ timeout,
742
+ )
743
+ time.sleep(0.1)
744
+
745
+ if self._state == TaskState.CANCELLED:
746
+ raise TaskCancelledError(f"Task {self.task_id} was cancelled", self.task_id)
747
+
748
+ if self._state == TaskState.FAILED:
749
+ raise DistributedError(
750
+ f"Task {self.task_id} failed: {self._error}",
751
+ {"exception": self._exception},
752
+ )
753
+
754
+ return self._result # type: ignore
755
+
756
+ async def result_async(self, timeout: float | None = None) -> T:
757
+ """Async version of result()."""
758
+ import asyncio
759
+
760
+ start = asyncio.get_event_loop().time()
761
+ while not self.is_ready():
762
+ if timeout and (asyncio.get_event_loop().time() - start) > timeout:
763
+ raise TaskTimeoutError(
764
+ f"Task {self.task_id} timed out",
765
+ self.task_id,
766
+ timeout,
767
+ )
768
+ await asyncio.sleep(0.1)
769
+
770
+ if self._state == TaskState.CANCELLED:
771
+ raise TaskCancelledError(f"Task {self.task_id} was cancelled", self.task_id)
772
+
773
+ if self._state == TaskState.FAILED:
774
+ raise DistributedError(
775
+ f"Task {self.task_id} failed: {self._error}",
776
+ {"exception": self._exception},
777
+ )
778
+
779
+ return self._result # type: ignore
780
+
781
+ def cancel(self, terminate: bool = False) -> bool:
782
+ """Cancel the task."""
783
+ if self.is_ready():
784
+ return False
785
+
786
+ self._state = TaskState.CANCELLED
787
+ self._completed_at = datetime.now()
788
+
789
+ # Notify backend if available
790
+ if self._backend and hasattr(self._backend, "cancel_task"):
791
+ try:
792
+ self._backend.cancel_task(self.task_id, terminate=terminate)
793
+ except Exception as e:
794
+ logger.warning(f"Backend cancel failed: {e}")
795
+
796
+ return True
797
+
798
+ def is_ready(self) -> bool:
799
+ """Check if task has completed."""
800
+ return self._state.is_terminal
801
+
802
+ def is_successful(self) -> bool:
803
+ """Check if task completed successfully."""
804
+ return self._state == TaskState.SUCCEEDED
805
+
806
+ def wait(self, timeout: float | None = None) -> bool:
807
+ """Wait for task to complete."""
808
+ try:
809
+ self.result(timeout=timeout)
810
+ return True
811
+ except TaskTimeoutError:
812
+ return False
813
+ except Exception:
814
+ return True # Task completed (with error)
815
+
816
+ def add_callback(
817
+ self,
818
+ callback: Callable[[T | None, Exception | None], None],
819
+ ) -> "DistributedTask[T]":
820
+ """Add a completion callback."""
821
+ self._callbacks.append(callback)
822
+ # If already complete, invoke immediately
823
+ if self.is_ready():
824
+ callback(self._result, self._exception)
825
+ return self
826
+
827
+ def to_result(self) -> DistributedTaskResult:
828
+ """Convert to DistributedTaskResult."""
829
+ return DistributedTaskResult(
830
+ task_id=self.task_id,
831
+ checkpoint_name=self.checkpoint_name,
832
+ state=self._state,
833
+ result=self._result, # type: ignore
834
+ error=self._error,
835
+ exception=self._exception,
836
+ worker_id=self._worker_id,
837
+ submitted_at=self._submitted_at,
838
+ started_at=self._started_at,
839
+ completed_at=self._completed_at,
840
+ retries=self._retries,
841
+ metadata=self._metadata,
842
+ )