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,865 @@
1
+ """Validator template CLI for scaffolding.
2
+
3
+ This module provides CLI tools for creating validator templates:
4
+ - Basic validator scaffold
5
+ - Category-specific templates
6
+ - Test file generation
7
+ - Project structure creation
8
+
9
+ Example:
10
+ from truthound.validators.sdk.enterprise.templates import (
11
+ TemplateCLI,
12
+ TemplateType,
13
+ create_validator_template,
14
+ )
15
+
16
+ # Create template
17
+ cli = TemplateCLI()
18
+ cli.create_validator(
19
+ name="my_validator",
20
+ category="custom",
21
+ template_type=TemplateType.COLUMN,
22
+ )
23
+ """
24
+
25
+ from __future__ import annotations
26
+
27
+ import logging
28
+ import os
29
+ from dataclasses import dataclass, field
30
+ from datetime import datetime, timezone
31
+ from enum import Enum, auto
32
+ from pathlib import Path
33
+ from typing import Any
34
+
35
+ logger = logging.getLogger(__name__)
36
+
37
+
38
+ class TemplateType(Enum):
39
+ """Types of validator templates."""
40
+
41
+ BASIC = auto() # Minimal validator
42
+ COLUMN = auto() # Column-level validator
43
+ AGGREGATE = auto() # Aggregate validator
44
+ PATTERN = auto() # Pattern matching validator
45
+ RANGE = auto() # Range checking validator
46
+ COMPARISON = auto() # Column comparison validator
47
+ COMPOSITE = auto() # Multi-validator composite
48
+ FULL = auto() # Full-featured with tests
49
+
50
+
51
+ @dataclass(frozen=True)
52
+ class TemplateConfig:
53
+ """Configuration for template generation.
54
+
55
+ Attributes:
56
+ name: Validator name
57
+ category: Validator category
58
+ template_type: Type of template
59
+ output_dir: Output directory
60
+ author: Author name
61
+ version: Initial version
62
+ description: Validator description
63
+ include_tests: Whether to generate test file
64
+ include_docs: Whether to generate documentation
65
+ license_type: License type
66
+ """
67
+
68
+ name: str
69
+ category: str = "custom"
70
+ template_type: TemplateType = TemplateType.BASIC
71
+ output_dir: Path = field(default_factory=lambda: Path("."))
72
+ author: str = ""
73
+ version: str = "1.0.0"
74
+ description: str = ""
75
+ include_tests: bool = True
76
+ include_docs: bool = True
77
+ license_type: str = "MIT"
78
+
79
+
80
+ @dataclass
81
+ class ValidatorTemplate:
82
+ """Generated validator template.
83
+
84
+ Attributes:
85
+ name: Validator name
86
+ source_code: Generated source code
87
+ test_code: Generated test code
88
+ documentation: Generated documentation
89
+ config: Template configuration used
90
+ """
91
+
92
+ name: str
93
+ source_code: str
94
+ test_code: str = ""
95
+ documentation: str = ""
96
+ config: TemplateConfig | None = None
97
+
98
+
99
+ class TemplateGenerator:
100
+ """Generates validator template code."""
101
+
102
+ def __init__(self, config: TemplateConfig):
103
+ """Initialize generator.
104
+
105
+ Args:
106
+ config: Template configuration
107
+ """
108
+ self.config = config
109
+
110
+ def _snake_to_pascal(self, name: str) -> str:
111
+ """Convert snake_case to PascalCase."""
112
+ return "".join(word.capitalize() for word in name.split("_"))
113
+
114
+ def _generate_basic(self) -> str:
115
+ """Generate basic validator template."""
116
+ class_name = self._snake_to_pascal(self.config.name) + "Validator"
117
+
118
+ return f'''"""
119
+ {self.config.description or f'{self.config.name} validator.'}
120
+
121
+ Author: {self.config.author or 'Unknown'}
122
+ Version: {self.config.version}
123
+ License: {self.config.license_type}
124
+ """
125
+
126
+ from __future__ import annotations
127
+
128
+ import polars as pl
129
+
130
+ from truthound.validators.base import Validator, ValidationIssue
131
+ from truthound.validators.sdk import custom_validator
132
+ from truthound.types import Severity
133
+
134
+
135
+ @custom_validator(
136
+ name="{self.config.name}",
137
+ category="{self.config.category}",
138
+ description="{self.config.description or f'{self.config.name} validator'}",
139
+ version="{self.config.version}",
140
+ author="{self.config.author}",
141
+ tags=["{self.config.category}"],
142
+ )
143
+ class {class_name}(Validator):
144
+ """{self.config.description or f'{self.config.name} validator.'}
145
+
146
+ Example:
147
+ validator = {class_name}()
148
+ issues = validator.validate(lf)
149
+ """
150
+
151
+ def validate(self, lf: pl.LazyFrame) -> list[ValidationIssue]:
152
+ """Validate the data.
153
+
154
+ Args:
155
+ lf: LazyFrame to validate
156
+
157
+ Returns:
158
+ List of validation issues found
159
+ """
160
+ issues: list[ValidationIssue] = []
161
+
162
+ # TODO: Implement validation logic
163
+
164
+ return issues
165
+ '''
166
+
167
+ def _generate_column(self) -> str:
168
+ """Generate column validator template."""
169
+ class_name = self._snake_to_pascal(self.config.name) + "Validator"
170
+
171
+ return f'''"""
172
+ {self.config.description or f'{self.config.name} column validator.'}
173
+
174
+ Author: {self.config.author or 'Unknown'}
175
+ Version: {self.config.version}
176
+ License: {self.config.license_type}
177
+ """
178
+
179
+ from __future__ import annotations
180
+
181
+ import polars as pl
182
+
183
+ from truthound.validators.base import (
184
+ ColumnValidator,
185
+ ValidationIssue,
186
+ ValidatorConfig,
187
+ )
188
+ from truthound.validators.sdk import custom_validator
189
+ from truthound.types import Severity
190
+
191
+
192
+ @custom_validator(
193
+ name="{self.config.name}",
194
+ category="{self.config.category}",
195
+ description="{self.config.description or f'{self.config.name} column validator'}",
196
+ version="{self.config.version}",
197
+ author="{self.config.author}",
198
+ tags=["{self.config.category}", "column"],
199
+ )
200
+ class {class_name}(ColumnValidator):
201
+ """{self.config.description or f'{self.config.name} column validator.'}
202
+
203
+ Validates each column that matches the configured criteria.
204
+
205
+ Example:
206
+ validator = {class_name}(columns=["value", "amount"])
207
+ issues = validator.validate(lf)
208
+ """
209
+
210
+ def __init__(
211
+ self,
212
+ config: ValidatorConfig | None = None,
213
+ columns: list[str] | None = None,
214
+ severity: Severity = Severity.MEDIUM,
215
+ **kwargs,
216
+ ):
217
+ """Initialize the validator.
218
+
219
+ Args:
220
+ config: Validator configuration
221
+ columns: Columns to validate (None = all applicable)
222
+ severity: Severity level for issues
223
+ """
224
+ super().__init__(config, **kwargs)
225
+ self._target_columns = columns
226
+ self._severity = severity
227
+
228
+ def validate_column(
229
+ self,
230
+ lf: pl.LazyFrame,
231
+ column: str,
232
+ ) -> list[ValidationIssue]:
233
+ """Validate a single column.
234
+
235
+ Args:
236
+ lf: LazyFrame to validate
237
+ column: Column name to validate
238
+
239
+ Returns:
240
+ List of validation issues for this column
241
+ """
242
+ issues: list[ValidationIssue] = []
243
+
244
+ # TODO: Implement column validation logic
245
+ # Example:
246
+ # violations = lf.filter(pl.col(column).is_null()).collect()
247
+ # if violations.height > 0:
248
+ # issues.append(ValidationIssue(
249
+ # column=column,
250
+ # issue_type="{self.config.name}",
251
+ # count=violations.height,
252
+ # severity=self._severity,
253
+ # details=f"Column '{{column}}' has {{violations.height}} issues",
254
+ # ))
255
+
256
+ return issues
257
+
258
+ def get_target_columns(self, lf: pl.LazyFrame) -> list[str]:
259
+ """Get columns to validate.
260
+
261
+ Args:
262
+ lf: LazyFrame to get columns from
263
+
264
+ Returns:
265
+ List of column names to validate
266
+ """
267
+ if self._target_columns:
268
+ return [c for c in self._target_columns if c in lf.columns]
269
+ return lf.columns
270
+ '''
271
+
272
+ def _generate_pattern(self) -> str:
273
+ """Generate pattern validator template."""
274
+ class_name = self._snake_to_pascal(self.config.name) + "Validator"
275
+
276
+ return f'''"""
277
+ {self.config.description or f'{self.config.name} pattern validator.'}
278
+
279
+ Author: {self.config.author or 'Unknown'}
280
+ Version: {self.config.version}
281
+ License: {self.config.license_type}
282
+ """
283
+
284
+ from __future__ import annotations
285
+
286
+ import re
287
+
288
+ import polars as pl
289
+
290
+ from truthound.validators.base import (
291
+ Validator,
292
+ ValidationIssue,
293
+ ValidatorConfig,
294
+ RegexValidatorMixin,
295
+ )
296
+ from truthound.validators.sdk import custom_validator
297
+ from truthound.types import Severity
298
+
299
+
300
+ @custom_validator(
301
+ name="{self.config.name}",
302
+ category="{self.config.category}",
303
+ description="{self.config.description or f'{self.config.name} pattern validator'}",
304
+ version="{self.config.version}",
305
+ author="{self.config.author}",
306
+ tags=["{self.config.category}", "pattern", "regex"],
307
+ )
308
+ class {class_name}(Validator, RegexValidatorMixin):
309
+ """{self.config.description or f'{self.config.name} pattern validator.'}
310
+
311
+ Validates values against a regex pattern.
312
+
313
+ Example:
314
+ validator = {class_name}(pattern=r"^[A-Z]{{2,3}}-\\d{{4}}$")
315
+ issues = validator.validate(lf)
316
+ """
317
+
318
+ def __init__(
319
+ self,
320
+ config: ValidatorConfig | None = None,
321
+ pattern: str = r".*",
322
+ columns: list[str] | None = None,
323
+ case_sensitive: bool = True,
324
+ invert: bool = False,
325
+ severity: Severity = Severity.MEDIUM,
326
+ **kwargs,
327
+ ):
328
+ """Initialize the validator.
329
+
330
+ Args:
331
+ config: Validator configuration
332
+ pattern: Regex pattern to match
333
+ columns: Columns to validate
334
+ case_sensitive: Whether pattern matching is case sensitive
335
+ invert: If True, match values that DON'T match the pattern
336
+ severity: Severity level for issues
337
+ """
338
+ super().__init__(config, **kwargs)
339
+ self._pattern_str = pattern
340
+ self._columns = columns
341
+ self._case_sensitive = case_sensitive
342
+ self._invert = invert
343
+ self._severity = severity
344
+
345
+ # Compile pattern
346
+ flags = 0 if case_sensitive else re.IGNORECASE
347
+ self._pattern = re.compile(pattern, flags)
348
+
349
+ def validate(self, lf: pl.LazyFrame) -> list[ValidationIssue]:
350
+ """Validate data against pattern.
351
+
352
+ Args:
353
+ lf: LazyFrame to validate
354
+
355
+ Returns:
356
+ List of validation issues
357
+ """
358
+ issues: list[ValidationIssue] = []
359
+
360
+ # Get string columns
361
+ columns = self._columns or [
362
+ col for col, dtype in zip(lf.columns, lf.dtypes)
363
+ if dtype == pl.Utf8 or dtype == pl.String
364
+ ]
365
+
366
+ for column in columns:
367
+ if column not in lf.columns:
368
+ continue
369
+
370
+ # Check pattern match
371
+ if self._invert:
372
+ # Find values that match (when we want non-matches)
373
+ violations = lf.filter(
374
+ pl.col(column).str.contains(self._pattern_str)
375
+ ).collect()
376
+ else:
377
+ # Find values that don't match (when we want matches)
378
+ violations = lf.filter(
379
+ ~pl.col(column).str.contains(self._pattern_str)
380
+ ).collect()
381
+
382
+ if violations.height > 0:
383
+ samples = violations[column].head(5).to_list()
384
+ issues.append(ValidationIssue(
385
+ column=column,
386
+ issue_type="{self.config.name}_pattern_mismatch",
387
+ count=violations.height,
388
+ severity=self._severity,
389
+ details=(
390
+ f"Column '{{column}}' has {{violations.height}} values that "
391
+ f"{'match' if self._invert else 'do not match'} "
392
+ f"pattern '{{self._pattern_str}}'"
393
+ ),
394
+ sample_values=samples,
395
+ ))
396
+
397
+ return issues
398
+ '''
399
+
400
+ def _generate_range(self) -> str:
401
+ """Generate range validator template."""
402
+ class_name = self._snake_to_pascal(self.config.name) + "Validator"
403
+
404
+ return f'''"""
405
+ {self.config.description or f'{self.config.name} range validator.'}
406
+
407
+ Author: {self.config.author or 'Unknown'}
408
+ Version: {self.config.version}
409
+ License: {self.config.license_type}
410
+ """
411
+
412
+ from __future__ import annotations
413
+
414
+ import polars as pl
415
+
416
+ from truthound.validators.base import (
417
+ Validator,
418
+ ValidationIssue,
419
+ ValidatorConfig,
420
+ NumericValidatorMixin,
421
+ NUMERIC_TYPES,
422
+ )
423
+ from truthound.validators.sdk import custom_validator
424
+ from truthound.types import Severity
425
+
426
+
427
+ @custom_validator(
428
+ name="{self.config.name}",
429
+ category="{self.config.category}",
430
+ description="{self.config.description or f'{self.config.name} range validator'}",
431
+ version="{self.config.version}",
432
+ author="{self.config.author}",
433
+ tags=["{self.config.category}", "range", "numeric"],
434
+ )
435
+ class {class_name}(Validator, NumericValidatorMixin):
436
+ """{self.config.description or f'{self.config.name} range validator.'}
437
+
438
+ Validates numeric values are within a specified range.
439
+
440
+ Example:
441
+ validator = {class_name}(min_value=0, max_value=100)
442
+ issues = validator.validate(lf)
443
+ """
444
+
445
+ def __init__(
446
+ self,
447
+ config: ValidatorConfig | None = None,
448
+ min_value: float | None = None,
449
+ max_value: float | None = None,
450
+ columns: list[str] | None = None,
451
+ inclusive: bool = True,
452
+ severity: Severity = Severity.MEDIUM,
453
+ **kwargs,
454
+ ):
455
+ """Initialize the validator.
456
+
457
+ Args:
458
+ config: Validator configuration
459
+ min_value: Minimum allowed value (None = no minimum)
460
+ max_value: Maximum allowed value (None = no maximum)
461
+ columns: Columns to validate
462
+ inclusive: Whether bounds are inclusive
463
+ severity: Severity level for issues
464
+ """
465
+ super().__init__(config, **kwargs)
466
+ self._min_value = min_value
467
+ self._max_value = max_value
468
+ self._columns = columns
469
+ self._inclusive = inclusive
470
+ self._severity = severity
471
+
472
+ def validate(self, lf: pl.LazyFrame) -> list[ValidationIssue]:
473
+ """Validate numeric values are in range.
474
+
475
+ Args:
476
+ lf: LazyFrame to validate
477
+
478
+ Returns:
479
+ List of validation issues
480
+ """
481
+ issues: list[ValidationIssue] = []
482
+
483
+ # Get numeric columns
484
+ columns = self._columns or [
485
+ col for col, dtype in zip(lf.columns, lf.dtypes)
486
+ if any(isinstance(dtype, t) for t in NUMERIC_TYPES)
487
+ ]
488
+
489
+ for column in columns:
490
+ if column not in lf.columns:
491
+ continue
492
+
493
+ # Build filter expression
494
+ conditions = []
495
+
496
+ if self._min_value is not None:
497
+ if self._inclusive:
498
+ conditions.append(pl.col(column) < self._min_value)
499
+ else:
500
+ conditions.append(pl.col(column) <= self._min_value)
501
+
502
+ if self._max_value is not None:
503
+ if self._inclusive:
504
+ conditions.append(pl.col(column) > self._max_value)
505
+ else:
506
+ conditions.append(pl.col(column) >= self._max_value)
507
+
508
+ if not conditions:
509
+ continue
510
+
511
+ # Combine conditions with OR
512
+ filter_expr = conditions[0]
513
+ for cond in conditions[1:]:
514
+ filter_expr = filter_expr | cond
515
+
516
+ violations = lf.filter(filter_expr).collect()
517
+
518
+ if violations.height > 0:
519
+ samples = violations[column].head(5).to_list()
520
+ range_str = f"[{{self._min_value}}, {{self._max_value}}]"
521
+ issues.append(ValidationIssue(
522
+ column=column,
523
+ issue_type="{self.config.name}_out_of_range",
524
+ count=violations.height,
525
+ severity=self._severity,
526
+ details=(
527
+ f"Column '{{column}}' has {{violations.height}} values "
528
+ f"outside range {{range_str}}"
529
+ ),
530
+ sample_values=samples,
531
+ ))
532
+
533
+ return issues
534
+ '''
535
+
536
+ def _generate_test(self) -> str:
537
+ """Generate test file template."""
538
+ class_name = self._snake_to_pascal(self.config.name) + "Validator"
539
+ test_class_name = f"Test{class_name}"
540
+
541
+ return f'''"""Tests for {class_name}."""
542
+
543
+ import pytest
544
+ import polars as pl
545
+
546
+ from truthound.validators.sdk.testing import (
547
+ ValidatorTestCase,
548
+ create_test_dataframe,
549
+ assert_no_issues,
550
+ assert_has_issue,
551
+ )
552
+ from .{self.config.name} import {class_name}
553
+
554
+
555
+ class {test_class_name}(ValidatorTestCase):
556
+ """Test cases for {class_name}."""
557
+
558
+ def test_valid_data(self):
559
+ """Test that valid data produces no issues."""
560
+ # Arrange
561
+ lf = pl.LazyFrame({{
562
+ "column1": [1, 2, 3],
563
+ "column2": ["a", "b", "c"],
564
+ }})
565
+ validator = {class_name}()
566
+
567
+ # Act
568
+ issues = validator.validate(lf)
569
+
570
+ # Assert
571
+ assert_no_issues(issues)
572
+
573
+ def test_invalid_data(self):
574
+ """Test that invalid data produces issues."""
575
+ # Arrange
576
+ lf = pl.LazyFrame({{
577
+ "column1": [None, 2, None],
578
+ "column2": ["a", None, "c"],
579
+ }})
580
+ validator = {class_name}()
581
+
582
+ # Act
583
+ issues = validator.validate(lf)
584
+
585
+ # Assert
586
+ # TODO: Update assertion based on your validation logic
587
+ # assert_has_issue(issues, issue_type="{self.config.name}")
588
+
589
+ def test_empty_dataframe(self):
590
+ """Test with empty dataframe."""
591
+ # Arrange
592
+ lf = pl.LazyFrame({{
593
+ "column1": [],
594
+ "column2": [],
595
+ }})
596
+ validator = {class_name}()
597
+
598
+ # Act
599
+ issues = validator.validate(lf)
600
+
601
+ # Assert
602
+ assert_no_issues(issues)
603
+
604
+ def test_configuration(self):
605
+ """Test validator configuration options."""
606
+ # TODO: Add configuration tests
607
+ pass
608
+
609
+ def test_edge_cases(self):
610
+ """Test edge cases."""
611
+ # TODO: Add edge case tests
612
+ pass
613
+ '''
614
+
615
+ def _generate_documentation(self) -> str:
616
+ """Generate documentation template."""
617
+ class_name = self._snake_to_pascal(self.config.name) + "Validator"
618
+
619
+ return f'''# {class_name}
620
+
621
+ > {self.config.category} validator
622
+
623
+ ## Description
624
+
625
+ {self.config.description or 'TODO: Add description'}
626
+
627
+ ## Installation
628
+
629
+ This validator is part of the Truthound package:
630
+
631
+ ```bash
632
+ pip install truthound
633
+ ```
634
+
635
+ ## Usage
636
+
637
+ ```python
638
+ from truthound.validators import {class_name}
639
+
640
+ # Create validator
641
+ validator = {class_name}()
642
+
643
+ # Validate data
644
+ issues = validator.validate(lf)
645
+ ```
646
+
647
+ ## Configuration
648
+
649
+ | Parameter | Type | Default | Description |
650
+ |-----------|------|---------|-------------|
651
+ | TODO | TODO | TODO | TODO |
652
+
653
+ ## Examples
654
+
655
+ ### Basic Usage
656
+
657
+ ```python
658
+ import polars as pl
659
+ from truthound.validators import {class_name}
660
+
661
+ # Create sample data
662
+ lf = pl.LazyFrame({{
663
+ "value": [1, 2, 3, 4, 5],
664
+ }})
665
+
666
+ # Create and run validator
667
+ validator = {class_name}()
668
+ issues = validator.validate(lf)
669
+
670
+ print(f"Found {{len(issues)}} issues")
671
+ ```
672
+
673
+ ## See Also
674
+
675
+ - [Validator SDK]({self.config.name}_sdk.md)
676
+ - [Testing Guide]({self.config.name}_testing.md)
677
+
678
+ ---
679
+
680
+ *Version: {self.config.version}*
681
+ *Author: {self.config.author or 'Unknown'}*
682
+ *License: {self.config.license_type}*
683
+ '''
684
+
685
+ def generate(self) -> ValidatorTemplate:
686
+ """Generate validator template.
687
+
688
+ Returns:
689
+ ValidatorTemplate with generated code
690
+ """
691
+ # Generate source code based on template type
692
+ generators = {
693
+ TemplateType.BASIC: self._generate_basic,
694
+ TemplateType.COLUMN: self._generate_column,
695
+ TemplateType.PATTERN: self._generate_pattern,
696
+ TemplateType.RANGE: self._generate_range,
697
+ TemplateType.AGGREGATE: self._generate_basic, # TODO: Add specific
698
+ TemplateType.COMPARISON: self._generate_basic, # TODO: Add specific
699
+ TemplateType.COMPOSITE: self._generate_basic, # TODO: Add specific
700
+ TemplateType.FULL: self._generate_column,
701
+ }
702
+
703
+ generator = generators.get(self.config.template_type, self._generate_basic)
704
+ source_code = generator()
705
+
706
+ # Generate test code
707
+ test_code = ""
708
+ if self.config.include_tests:
709
+ test_code = self._generate_test()
710
+
711
+ # Generate documentation
712
+ documentation = ""
713
+ if self.config.include_docs:
714
+ documentation = self._generate_documentation()
715
+
716
+ return ValidatorTemplate(
717
+ name=self.config.name,
718
+ source_code=source_code,
719
+ test_code=test_code,
720
+ documentation=documentation,
721
+ config=self.config,
722
+ )
723
+
724
+
725
+ class TemplateCLI:
726
+ """CLI for creating validator templates."""
727
+
728
+ def __init__(self, output_dir: Path | None = None):
729
+ """Initialize CLI.
730
+
731
+ Args:
732
+ output_dir: Default output directory
733
+ """
734
+ self.output_dir = output_dir or Path(".")
735
+
736
+ def create_validator(
737
+ self,
738
+ name: str,
739
+ category: str = "custom",
740
+ template_type: TemplateType = TemplateType.BASIC,
741
+ output_dir: Path | None = None,
742
+ author: str = "",
743
+ description: str = "",
744
+ include_tests: bool = True,
745
+ include_docs: bool = True,
746
+ ) -> dict[str, Path]:
747
+ """Create a new validator from template.
748
+
749
+ Args:
750
+ name: Validator name (snake_case)
751
+ category: Validator category
752
+ template_type: Type of template to use
753
+ output_dir: Output directory
754
+ author: Author name
755
+ description: Validator description
756
+ include_tests: Generate test file
757
+ include_docs: Generate documentation
758
+
759
+ Returns:
760
+ Dictionary of file type to path
761
+ """
762
+ output_dir = output_dir or self.output_dir
763
+
764
+ config = TemplateConfig(
765
+ name=name,
766
+ category=category,
767
+ template_type=template_type,
768
+ output_dir=output_dir,
769
+ author=author,
770
+ description=description,
771
+ include_tests=include_tests,
772
+ include_docs=include_docs,
773
+ )
774
+
775
+ generator = TemplateGenerator(config)
776
+ template = generator.generate()
777
+
778
+ # Create output directory
779
+ validator_dir = output_dir / name
780
+ validator_dir.mkdir(parents=True, exist_ok=True)
781
+
782
+ created_files: dict[str, Path] = {}
783
+
784
+ # Write source code
785
+ source_path = validator_dir / f"{name}.py"
786
+ with open(source_path, "w") as f:
787
+ f.write(template.source_code)
788
+ created_files["source"] = source_path
789
+
790
+ # Write init file
791
+ init_path = validator_dir / "__init__.py"
792
+ class_name = generator._snake_to_pascal(name) + "Validator"
793
+ with open(init_path, "w") as f:
794
+ f.write(f'from .{name} import {class_name}\n\n__all__ = ["{class_name}"]\n')
795
+ created_files["init"] = init_path
796
+
797
+ # Write test file
798
+ if template.test_code:
799
+ tests_dir = validator_dir / "tests"
800
+ tests_dir.mkdir(exist_ok=True)
801
+ test_path = tests_dir / f"test_{name}.py"
802
+ with open(test_path, "w") as f:
803
+ f.write(template.test_code)
804
+ created_files["test"] = test_path
805
+
806
+ # Tests init
807
+ tests_init = tests_dir / "__init__.py"
808
+ with open(tests_init, "w") as f:
809
+ f.write("")
810
+ created_files["test_init"] = tests_init
811
+
812
+ # Write documentation
813
+ if template.documentation:
814
+ docs_dir = validator_dir / "docs"
815
+ docs_dir.mkdir(exist_ok=True)
816
+ docs_path = docs_dir / f"{name}.md"
817
+ with open(docs_path, "w") as f:
818
+ f.write(template.documentation)
819
+ created_files["docs"] = docs_path
820
+
821
+ return created_files
822
+
823
+ def list_templates(self) -> list[dict[str, str]]:
824
+ """List available templates.
825
+
826
+ Returns:
827
+ List of template info dictionaries
828
+ """
829
+ return [
830
+ {
831
+ "type": t.name,
832
+ "description": {
833
+ TemplateType.BASIC: "Minimal validator template",
834
+ TemplateType.COLUMN: "Column-level validator with target column support",
835
+ TemplateType.AGGREGATE: "Aggregate validator for statistical checks",
836
+ TemplateType.PATTERN: "Pattern matching validator with regex support",
837
+ TemplateType.RANGE: "Range checking validator for numeric columns",
838
+ TemplateType.COMPARISON: "Column comparison validator",
839
+ TemplateType.COMPOSITE: "Multi-validator composite",
840
+ TemplateType.FULL: "Full-featured with tests and documentation",
841
+ }.get(t, ""),
842
+ }
843
+ for t in TemplateType
844
+ ]
845
+
846
+
847
+ def create_validator_template(
848
+ name: str,
849
+ category: str = "custom",
850
+ template_type: TemplateType = TemplateType.BASIC,
851
+ output_dir: Path | None = None,
852
+ ) -> dict[str, Path]:
853
+ """Create a new validator from template.
854
+
855
+ Args:
856
+ name: Validator name
857
+ category: Validator category
858
+ template_type: Template type
859
+ output_dir: Output directory
860
+
861
+ Returns:
862
+ Dictionary of created file paths
863
+ """
864
+ cli = TemplateCLI(output_dir)
865
+ return cli.create_validator(name, category, template_type)