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,709 @@
1
+ """RE2 Engine - Linear Time Regex Matching.
2
+
3
+ This module provides integration with Google's RE2 regex engine,
4
+ which guarantees linear time matching by avoiding backtracking.
5
+
6
+ Architecture:
7
+ ┌─────────────────────────────────────────────────────────────────┐
8
+ │ RE2 Engine Wrapper │
9
+ └─────────────────────────────────────────────────────────────────┘
10
+
11
+ ┌───────────────┬───────────────┼───────────────┬─────────────────┐
12
+ │ │ │ │ │
13
+ ▼ ▼ ▼ ▼ ▼
14
+ ┌─────────┐ ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐
15
+ │ Pattern │ │ Fallback│ │ Feature │ │ Compat │ │ Perf │
16
+ │ Compiler│ │ Handler │ │ Detector │ │ Converter│ │ Monitor │
17
+ └─────────┘ └─────────┘ └──────────┘ └──────────┘ └─────────┘
18
+
19
+ RE2 Advantages:
20
+ - Guaranteed O(n) matching time
21
+ - No catastrophic backtracking
22
+ - Memory-bounded matching
23
+
24
+ RE2 Limitations (handled by this module):
25
+ - No backreferences (\\1, \\2, etc.)
26
+ - No lookahead/lookbehind
27
+ - Limited Unicode support
28
+ - Different capture group semantics
29
+
30
+ Usage:
31
+ from truthound.validators.security.redos.re2_engine import (
32
+ RE2Engine,
33
+ safe_match_re2,
34
+ )
35
+
36
+ # Quick RE2 match
37
+ result = safe_match_re2(r"^[a-z]+$", "hello")
38
+ if result.matched:
39
+ print(f"Matched: {result.match}")
40
+
41
+ # Full engine with fallback
42
+ engine = RE2Engine(fallback_to_python=True)
43
+ result = engine.match(r"(a+)\\1", "aa") # Falls back to Python
44
+ """
45
+
46
+ from __future__ import annotations
47
+
48
+ import re
49
+ from abc import ABC, abstractmethod
50
+ from dataclasses import dataclass, field
51
+ from enum import Enum, auto
52
+ from typing import Any, Protocol, Sequence
53
+
54
+ # Try to import re2 library
55
+ try:
56
+ import re2
57
+ HAS_RE2 = True
58
+ except ImportError:
59
+ re2 = None # type: ignore
60
+ HAS_RE2 = False
61
+
62
+
63
+ class RE2UnsupportedFeature(Enum):
64
+ """Features not supported by RE2."""
65
+
66
+ BACKREFERENCE = auto()
67
+ LOOKAHEAD = auto()
68
+ LOOKBEHIND = auto()
69
+ ATOMIC_GROUP = auto()
70
+ POSSESSIVE_QUANTIFIER = auto()
71
+ CONDITIONAL = auto()
72
+ RECURSION = auto()
73
+ UNICODE_CATEGORY = auto()
74
+
75
+
76
+ class RE2CompileError(Exception):
77
+ """Error compiling pattern with RE2."""
78
+
79
+ def __init__(
80
+ self,
81
+ message: str,
82
+ pattern: str,
83
+ unsupported_features: list[RE2UnsupportedFeature] | None = None,
84
+ ):
85
+ super().__init__(message)
86
+ self.pattern = pattern
87
+ self.unsupported_features = unsupported_features or []
88
+
89
+
90
+ @dataclass
91
+ class RE2MatchResult:
92
+ """Result of RE2 matching operation.
93
+
94
+ Attributes:
95
+ pattern: The pattern used
96
+ input_string: The input string (truncated)
97
+ matched: Whether the pattern matched
98
+ match: The matched string (if any)
99
+ groups: Captured groups
100
+ span: Match span (start, end)
101
+ used_fallback: Whether Python re was used as fallback
102
+ engine: Engine used ("re2" or "python_re")
103
+ compile_time_ns: Time to compile pattern
104
+ match_time_ns: Time to perform match
105
+ """
106
+
107
+ pattern: str
108
+ input_string: str
109
+ matched: bool = False
110
+ match: str | None = None
111
+ groups: tuple[str | None, ...] = field(default_factory=tuple)
112
+ span: tuple[int, int] = (0, 0)
113
+ used_fallback: bool = False
114
+ engine: str = "re2"
115
+ compile_time_ns: int = 0
116
+ match_time_ns: int = 0
117
+
118
+ def to_dict(self) -> dict[str, Any]:
119
+ """Convert to dictionary."""
120
+ return {
121
+ "pattern": self.pattern,
122
+ "input_string": self.input_string[:100],
123
+ "matched": self.matched,
124
+ "match": self.match,
125
+ "groups": self.groups,
126
+ "span": self.span,
127
+ "used_fallback": self.used_fallback,
128
+ "engine": self.engine,
129
+ "compile_time_us": self.compile_time_ns / 1000,
130
+ "match_time_us": self.match_time_ns / 1000,
131
+ }
132
+
133
+
134
+ class RegexEngineProtocol(Protocol):
135
+ """Protocol for regex engine implementations."""
136
+
137
+ def compile(self, pattern: str, flags: int = 0) -> Any:
138
+ """Compile a pattern."""
139
+ ...
140
+
141
+ def match(self, pattern: str, string: str, flags: int = 0) -> RE2MatchResult:
142
+ """Match pattern against string."""
143
+ ...
144
+
145
+ def search(self, pattern: str, string: str, flags: int = 0) -> RE2MatchResult:
146
+ """Search for pattern in string."""
147
+ ...
148
+
149
+
150
+ class FeatureDetector:
151
+ """Detect unsupported RE2 features in patterns."""
152
+
153
+ # Patterns for unsupported features
154
+ FEATURE_PATTERNS: list[tuple[str, RE2UnsupportedFeature]] = [
155
+ (r"\\[1-9]\d*", RE2UnsupportedFeature.BACKREFERENCE),
156
+ (r"\(\?=", RE2UnsupportedFeature.LOOKAHEAD),
157
+ (r"\(\?!", RE2UnsupportedFeature.LOOKAHEAD),
158
+ (r"\(\?<=", RE2UnsupportedFeature.LOOKBEHIND),
159
+ (r"\(\?<!", RE2UnsupportedFeature.LOOKBEHIND),
160
+ (r"\(\?>", RE2UnsupportedFeature.ATOMIC_GROUP),
161
+ (r"[+*?]\+", RE2UnsupportedFeature.POSSESSIVE_QUANTIFIER),
162
+ (r"\(\?\(", RE2UnsupportedFeature.CONDITIONAL),
163
+ (r"\(\?R\)", RE2UnsupportedFeature.RECURSION),
164
+ (r"\(\?\d+\)", RE2UnsupportedFeature.RECURSION),
165
+ (r"\\p\{", RE2UnsupportedFeature.UNICODE_CATEGORY),
166
+ (r"\\P\{", RE2UnsupportedFeature.UNICODE_CATEGORY),
167
+ ]
168
+
169
+ def __init__(self):
170
+ """Initialize detector with compiled patterns."""
171
+ self._compiled = [
172
+ (re.compile(pattern), feature)
173
+ for pattern, feature in self.FEATURE_PATTERNS
174
+ ]
175
+
176
+ def detect(self, pattern: str) -> list[RE2UnsupportedFeature]:
177
+ """Detect unsupported features in a pattern.
178
+
179
+ Args:
180
+ pattern: Regex pattern to check
181
+
182
+ Returns:
183
+ List of unsupported features found
184
+ """
185
+ found: list[RE2UnsupportedFeature] = []
186
+
187
+ for compiled, feature in self._compiled:
188
+ if compiled.search(pattern):
189
+ if feature not in found:
190
+ found.append(feature)
191
+
192
+ return found
193
+
194
+ def is_re2_compatible(self, pattern: str) -> bool:
195
+ """Check if pattern is compatible with RE2.
196
+
197
+ Args:
198
+ pattern: Regex pattern
199
+
200
+ Returns:
201
+ True if pattern can be compiled with RE2
202
+ """
203
+ return len(self.detect(pattern)) == 0
204
+
205
+
206
+ class PatternConverter:
207
+ """Convert patterns to RE2-compatible form where possible."""
208
+
209
+ def convert(self, pattern: str) -> tuple[str, list[str]]:
210
+ """Attempt to convert pattern to RE2-compatible form.
211
+
212
+ Args:
213
+ pattern: Original pattern
214
+
215
+ Returns:
216
+ Tuple of (converted_pattern, warnings)
217
+
218
+ Note:
219
+ Not all patterns can be converted. Backreferences
220
+ and lookaround cannot be emulated in RE2.
221
+ """
222
+ warnings: list[str] = []
223
+ result = pattern
224
+
225
+ # Remove possessive quantifiers (convert to greedy)
226
+ if re.search(r"[+*?]\+", result):
227
+ result = re.sub(r"([+*?])\+", r"\1", result)
228
+ warnings.append("Possessive quantifiers converted to greedy")
229
+
230
+ # Note: We can't convert backreferences or lookaround
231
+ if re.search(r"\\[1-9]", result):
232
+ warnings.append("Backreferences cannot be converted to RE2")
233
+
234
+ if re.search(r"\(\?[=!<]", result):
235
+ warnings.append("Lookaround cannot be converted to RE2")
236
+
237
+ return result, warnings
238
+
239
+
240
+ class RE2Wrapper:
241
+ """Wrapper around RE2 library with pattern caching."""
242
+
243
+ def __init__(self, max_cache_size: int = 100):
244
+ """Initialize RE2 wrapper.
245
+
246
+ Args:
247
+ max_cache_size: Maximum patterns to cache
248
+ """
249
+ self._cache: dict[str, Any] = {}
250
+ self._max_cache_size = max_cache_size
251
+
252
+ def compile(self, pattern: str, flags: int = 0) -> Any:
253
+ """Compile pattern with RE2.
254
+
255
+ Args:
256
+ pattern: Regex pattern
257
+ flags: Regex flags
258
+
259
+ Returns:
260
+ Compiled RE2 pattern
261
+
262
+ Raises:
263
+ RE2CompileError: If pattern cannot be compiled
264
+ """
265
+ if not HAS_RE2:
266
+ raise RE2CompileError(
267
+ "RE2 library not installed. Install with: pip install google-re2",
268
+ pattern,
269
+ )
270
+
271
+ cache_key = f"{pattern}:{flags}"
272
+ if cache_key in self._cache:
273
+ return self._cache[cache_key]
274
+
275
+ # Check for unsupported features
276
+ detector = FeatureDetector()
277
+ unsupported = detector.detect(pattern)
278
+ if unsupported:
279
+ features_str = ", ".join(f.name for f in unsupported)
280
+ raise RE2CompileError(
281
+ f"Pattern contains features not supported by RE2: {features_str}",
282
+ pattern,
283
+ unsupported,
284
+ )
285
+
286
+ try:
287
+ compiled = re2.compile(pattern)
288
+
289
+ # Cache the compiled pattern
290
+ if len(self._cache) >= self._max_cache_size:
291
+ # Remove oldest entry
292
+ oldest = next(iter(self._cache))
293
+ del self._cache[oldest]
294
+
295
+ self._cache[cache_key] = compiled
296
+ return compiled
297
+
298
+ except Exception as e:
299
+ raise RE2CompileError(
300
+ f"RE2 compilation failed: {e}",
301
+ pattern,
302
+ )
303
+
304
+ def match(self, compiled: Any, string: str) -> Any:
305
+ """Match using compiled pattern."""
306
+ if not HAS_RE2:
307
+ raise RuntimeError("RE2 not available")
308
+ return compiled.match(string)
309
+
310
+ def search(self, compiled: Any, string: str) -> Any:
311
+ """Search using compiled pattern."""
312
+ if not HAS_RE2:
313
+ raise RuntimeError("RE2 not available")
314
+ return compiled.search(string)
315
+
316
+ def findall(self, compiled: Any, string: str) -> list[Any]:
317
+ """Find all matches using compiled pattern."""
318
+ if not HAS_RE2:
319
+ raise RuntimeError("RE2 not available")
320
+ return compiled.findall(string)
321
+
322
+
323
+ class PythonRegexFallback:
324
+ """Fallback to Python re module."""
325
+
326
+ def __init__(self, timeout_seconds: float = 5.0):
327
+ """Initialize fallback with timeout.
328
+
329
+ Args:
330
+ timeout_seconds: Maximum execution time
331
+ """
332
+ self.timeout_seconds = timeout_seconds
333
+ self._cache: dict[str, re.Pattern] = {}
334
+
335
+ def compile(self, pattern: str, flags: int = 0) -> re.Pattern:
336
+ """Compile with Python re."""
337
+ cache_key = f"{pattern}:{flags}"
338
+ if cache_key not in self._cache:
339
+ self._cache[cache_key] = re.compile(pattern, flags)
340
+ return self._cache[cache_key]
341
+
342
+ def match(self, compiled: re.Pattern, string: str) -> re.Match | None:
343
+ """Match using Python re."""
344
+ return compiled.match(string)
345
+
346
+ def search(self, compiled: re.Pattern, string: str) -> re.Match | None:
347
+ """Search using Python re."""
348
+ return compiled.search(string)
349
+
350
+
351
+ class RE2Engine:
352
+ """High-level RE2 engine with Python fallback.
353
+
354
+ This engine provides a simple interface for regex matching that
355
+ uses RE2 when possible for guaranteed linear-time matching, with
356
+ optional fallback to Python's re module for patterns that use
357
+ features not supported by RE2.
358
+
359
+ Example:
360
+ engine = RE2Engine()
361
+
362
+ # Simple match
363
+ result = engine.match(r"^[a-z]+$", "hello")
364
+ if result.matched:
365
+ print(f"Matched: {result.match}")
366
+
367
+ # Pattern with backreference (needs fallback)
368
+ engine_with_fallback = RE2Engine(fallback_to_python=True)
369
+ result = engine_with_fallback.match(r"(a+)\\1", "aa")
370
+ print(f"Used fallback: {result.used_fallback}") # True
371
+ """
372
+
373
+ def __init__(
374
+ self,
375
+ fallback_to_python: bool = True,
376
+ max_cache_size: int = 100,
377
+ python_timeout: float = 5.0,
378
+ ):
379
+ """Initialize the engine.
380
+
381
+ Args:
382
+ fallback_to_python: Use Python re for unsupported patterns
383
+ max_cache_size: Maximum compiled patterns to cache
384
+ python_timeout: Timeout for Python fallback
385
+ """
386
+ self.fallback_to_python = fallback_to_python
387
+ self._re2 = RE2Wrapper(max_cache_size) if HAS_RE2 else None
388
+ self._python = PythonRegexFallback(python_timeout)
389
+ self._detector = FeatureDetector()
390
+ self._converter = PatternConverter()
391
+
392
+ @property
393
+ def re2_available(self) -> bool:
394
+ """Check if RE2 is available."""
395
+ return HAS_RE2
396
+
397
+ def is_pattern_re2_compatible(self, pattern: str) -> bool:
398
+ """Check if pattern can be used with RE2.
399
+
400
+ Args:
401
+ pattern: Regex pattern
402
+
403
+ Returns:
404
+ True if pattern is RE2-compatible
405
+ """
406
+ return self._detector.is_re2_compatible(pattern)
407
+
408
+ def get_unsupported_features(self, pattern: str) -> list[RE2UnsupportedFeature]:
409
+ """Get list of unsupported features in pattern.
410
+
411
+ Args:
412
+ pattern: Regex pattern
413
+
414
+ Returns:
415
+ List of unsupported features
416
+ """
417
+ return self._detector.detect(pattern)
418
+
419
+ def match(
420
+ self,
421
+ pattern: str,
422
+ string: str,
423
+ flags: int = 0,
424
+ ) -> RE2MatchResult:
425
+ """Match pattern against string.
426
+
427
+ Uses RE2 if available and pattern is compatible,
428
+ otherwise falls back to Python re if enabled.
429
+
430
+ Args:
431
+ pattern: Regex pattern
432
+ string: String to match
433
+ flags: Regex flags
434
+
435
+ Returns:
436
+ RE2MatchResult with match information
437
+
438
+ Raises:
439
+ RE2CompileError: If pattern not supported and no fallback
440
+ """
441
+ return self._execute("match", pattern, string, flags)
442
+
443
+ def search(
444
+ self,
445
+ pattern: str,
446
+ string: str,
447
+ flags: int = 0,
448
+ ) -> RE2MatchResult:
449
+ """Search for pattern in string.
450
+
451
+ Args:
452
+ pattern: Regex pattern
453
+ string: String to search
454
+ flags: Regex flags
455
+
456
+ Returns:
457
+ RE2MatchResult with search result
458
+ """
459
+ return self._execute("search", pattern, string, flags)
460
+
461
+ def findall(
462
+ self,
463
+ pattern: str,
464
+ string: str,
465
+ flags: int = 0,
466
+ ) -> list[str]:
467
+ """Find all matches of pattern in string.
468
+
469
+ Args:
470
+ pattern: Regex pattern
471
+ string: String to search
472
+ flags: Regex flags
473
+
474
+ Returns:
475
+ List of matches
476
+ """
477
+ result = self._execute("findall", pattern, string, flags)
478
+ # Extract matches from result
479
+ if isinstance(result.match, list):
480
+ return result.match
481
+ return []
482
+
483
+ def _execute(
484
+ self,
485
+ operation: str,
486
+ pattern: str,
487
+ string: str,
488
+ flags: int = 0,
489
+ ) -> RE2MatchResult:
490
+ """Execute a regex operation.
491
+
492
+ Args:
493
+ operation: "match", "search", or "findall"
494
+ pattern: Regex pattern
495
+ string: Input string
496
+ flags: Regex flags
497
+
498
+ Returns:
499
+ RE2MatchResult
500
+ """
501
+ import time
502
+
503
+ # Try RE2 first
504
+ if HAS_RE2 and self._re2:
505
+ try:
506
+ compile_start = time.perf_counter_ns()
507
+ compiled = self._re2.compile(pattern, flags)
508
+ compile_time = time.perf_counter_ns() - compile_start
509
+
510
+ match_start = time.perf_counter_ns()
511
+ if operation == "match":
512
+ result = self._re2.match(compiled, string)
513
+ elif operation == "search":
514
+ result = self._re2.search(compiled, string)
515
+ else: # findall
516
+ result = self._re2.findall(compiled, string)
517
+ match_time = time.perf_counter_ns() - match_start
518
+
519
+ return self._create_result(
520
+ pattern, string, result, operation,
521
+ engine="re2",
522
+ compile_time=compile_time,
523
+ match_time=match_time,
524
+ )
525
+
526
+ except RE2CompileError as e:
527
+ if not self.fallback_to_python:
528
+ # Re-raise with pattern info
529
+ raise RE2CompileError(
530
+ f"Pattern not supported by RE2 and fallback disabled: {e}",
531
+ pattern,
532
+ e.unsupported_features,
533
+ )
534
+ # Fall through to Python fallback
535
+
536
+ # Fallback to Python re
537
+ if self.fallback_to_python:
538
+ try:
539
+ compile_start = time.perf_counter_ns()
540
+ compiled = self._python.compile(pattern, flags)
541
+ compile_time = time.perf_counter_ns() - compile_start
542
+
543
+ match_start = time.perf_counter_ns()
544
+ if operation == "match":
545
+ result = self._python.match(compiled, string)
546
+ elif operation == "search":
547
+ result = self._python.search(compiled, string)
548
+ else: # findall
549
+ result = compiled.findall(string)
550
+ match_time = time.perf_counter_ns() - match_start
551
+
552
+ return self._create_result(
553
+ pattern, string, result, operation,
554
+ engine="python_re",
555
+ used_fallback=True,
556
+ compile_time=compile_time,
557
+ match_time=match_time,
558
+ )
559
+
560
+ except re.error as e:
561
+ return RE2MatchResult(
562
+ pattern=pattern,
563
+ input_string=string[:100],
564
+ matched=False,
565
+ engine="python_re",
566
+ used_fallback=True,
567
+ )
568
+
569
+ raise RE2CompileError(
570
+ "RE2 not available and fallback disabled",
571
+ pattern,
572
+ )
573
+
574
+ def _create_result(
575
+ self,
576
+ pattern: str,
577
+ string: str,
578
+ match_result: Any,
579
+ operation: str,
580
+ engine: str = "re2",
581
+ used_fallback: bool = False,
582
+ compile_time: int = 0,
583
+ match_time: int = 0,
584
+ ) -> RE2MatchResult:
585
+ """Create result from match."""
586
+ if operation == "findall":
587
+ return RE2MatchResult(
588
+ pattern=pattern,
589
+ input_string=string[:100],
590
+ matched=bool(match_result),
591
+ match=match_result if match_result else None,
592
+ engine=engine,
593
+ used_fallback=used_fallback,
594
+ compile_time_ns=compile_time,
595
+ match_time_ns=match_time,
596
+ )
597
+
598
+ if match_result is None:
599
+ return RE2MatchResult(
600
+ pattern=pattern,
601
+ input_string=string[:100],
602
+ matched=False,
603
+ engine=engine,
604
+ used_fallback=used_fallback,
605
+ compile_time_ns=compile_time,
606
+ match_time_ns=match_time,
607
+ )
608
+
609
+ return RE2MatchResult(
610
+ pattern=pattern,
611
+ input_string=string[:100],
612
+ matched=True,
613
+ match=match_result.group(0),
614
+ groups=match_result.groups() if hasattr(match_result, 'groups') else (),
615
+ span=match_result.span() if hasattr(match_result, 'span') else (0, 0),
616
+ engine=engine,
617
+ used_fallback=used_fallback,
618
+ compile_time_ns=compile_time,
619
+ match_time_ns=match_time,
620
+ )
621
+
622
+
623
+ # ============================================================================
624
+ # Convenience functions
625
+ # ============================================================================
626
+
627
+
628
+ # Singleton engine instance
629
+ _default_engine: RE2Engine | None = None
630
+
631
+
632
+ def get_default_engine() -> RE2Engine:
633
+ """Get the default RE2 engine instance."""
634
+ global _default_engine
635
+ if _default_engine is None:
636
+ _default_engine = RE2Engine(fallback_to_python=True)
637
+ return _default_engine
638
+
639
+
640
+ def safe_match_re2(
641
+ pattern: str,
642
+ string: str,
643
+ flags: int = 0,
644
+ ) -> RE2MatchResult:
645
+ """Match pattern against string using RE2.
646
+
647
+ Args:
648
+ pattern: Regex pattern
649
+ string: String to match
650
+ flags: Regex flags
651
+
652
+ Returns:
653
+ RE2MatchResult with match information
654
+
655
+ Example:
656
+ result = safe_match_re2(r"^[a-z]+$", "hello")
657
+ if result.matched:
658
+ print(f"Match: {result.match}")
659
+ print(f"Engine: {result.engine}")
660
+ """
661
+ engine = get_default_engine()
662
+ return engine.match(pattern, string, flags)
663
+
664
+
665
+ def safe_search_re2(
666
+ pattern: str,
667
+ string: str,
668
+ flags: int = 0,
669
+ ) -> RE2MatchResult:
670
+ """Search for pattern in string using RE2.
671
+
672
+ Args:
673
+ pattern: Regex pattern
674
+ string: String to search
675
+ flags: Regex flags
676
+
677
+ Returns:
678
+ RE2MatchResult with search result
679
+ """
680
+ engine = get_default_engine()
681
+ return engine.search(pattern, string, flags)
682
+
683
+
684
+ def is_re2_available() -> bool:
685
+ """Check if RE2 library is available.
686
+
687
+ Returns:
688
+ True if google-re2 is installed
689
+ """
690
+ return HAS_RE2
691
+
692
+
693
+ def check_re2_compatibility(pattern: str) -> tuple[bool, list[RE2UnsupportedFeature]]:
694
+ """Check if a pattern is compatible with RE2.
695
+
696
+ Args:
697
+ pattern: Regex pattern to check
698
+
699
+ Returns:
700
+ Tuple of (is_compatible, unsupported_features)
701
+
702
+ Example:
703
+ compatible, unsupported = check_re2_compatibility(r"(a+)\\1")
704
+ if not compatible:
705
+ print(f"Unsupported: {[f.name for f in unsupported]}")
706
+ """
707
+ detector = FeatureDetector()
708
+ unsupported = detector.detect(pattern)
709
+ return len(unsupported) == 0, unsupported