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.
- truthound/__init__.py +162 -0
- truthound/adapters.py +100 -0
- truthound/api.py +365 -0
- truthound/audit/__init__.py +248 -0
- truthound/audit/core.py +967 -0
- truthound/audit/filters.py +620 -0
- truthound/audit/formatters.py +707 -0
- truthound/audit/logger.py +902 -0
- truthound/audit/middleware.py +571 -0
- truthound/audit/storage.py +1083 -0
- truthound/benchmark/__init__.py +123 -0
- truthound/benchmark/base.py +757 -0
- truthound/benchmark/comparison.py +635 -0
- truthound/benchmark/generators.py +706 -0
- truthound/benchmark/reporters.py +718 -0
- truthound/benchmark/runner.py +635 -0
- truthound/benchmark/scenarios.py +712 -0
- truthound/cache.py +252 -0
- truthound/checkpoint/__init__.py +136 -0
- truthound/checkpoint/actions/__init__.py +164 -0
- truthound/checkpoint/actions/base.py +324 -0
- truthound/checkpoint/actions/custom.py +234 -0
- truthound/checkpoint/actions/discord_notify.py +290 -0
- truthound/checkpoint/actions/email_notify.py +405 -0
- truthound/checkpoint/actions/github_action.py +406 -0
- truthound/checkpoint/actions/opsgenie.py +1499 -0
- truthound/checkpoint/actions/pagerduty.py +226 -0
- truthound/checkpoint/actions/slack_notify.py +233 -0
- truthound/checkpoint/actions/store_result.py +249 -0
- truthound/checkpoint/actions/teams_notify.py +1570 -0
- truthound/checkpoint/actions/telegram_notify.py +419 -0
- truthound/checkpoint/actions/update_docs.py +552 -0
- truthound/checkpoint/actions/webhook.py +293 -0
- truthound/checkpoint/analytics/__init__.py +147 -0
- truthound/checkpoint/analytics/aggregations/__init__.py +23 -0
- truthound/checkpoint/analytics/aggregations/rollup.py +481 -0
- truthound/checkpoint/analytics/aggregations/time_bucket.py +306 -0
- truthound/checkpoint/analytics/analyzers/__init__.py +17 -0
- truthound/checkpoint/analytics/analyzers/anomaly.py +386 -0
- truthound/checkpoint/analytics/analyzers/base.py +270 -0
- truthound/checkpoint/analytics/analyzers/forecast.py +421 -0
- truthound/checkpoint/analytics/analyzers/trend.py +314 -0
- truthound/checkpoint/analytics/models.py +292 -0
- truthound/checkpoint/analytics/protocols.py +549 -0
- truthound/checkpoint/analytics/service.py +718 -0
- truthound/checkpoint/analytics/stores/__init__.py +16 -0
- truthound/checkpoint/analytics/stores/base.py +306 -0
- truthound/checkpoint/analytics/stores/memory_store.py +353 -0
- truthound/checkpoint/analytics/stores/sqlite_store.py +557 -0
- truthound/checkpoint/analytics/stores/timescale_store.py +501 -0
- truthound/checkpoint/async_actions.py +794 -0
- truthound/checkpoint/async_base.py +708 -0
- truthound/checkpoint/async_checkpoint.py +617 -0
- truthound/checkpoint/async_runner.py +639 -0
- truthound/checkpoint/checkpoint.py +527 -0
- truthound/checkpoint/ci/__init__.py +61 -0
- truthound/checkpoint/ci/detector.py +355 -0
- truthound/checkpoint/ci/reporter.py +436 -0
- truthound/checkpoint/ci/templates.py +454 -0
- truthound/checkpoint/circuitbreaker/__init__.py +133 -0
- truthound/checkpoint/circuitbreaker/breaker.py +542 -0
- truthound/checkpoint/circuitbreaker/core.py +252 -0
- truthound/checkpoint/circuitbreaker/detection.py +459 -0
- truthound/checkpoint/circuitbreaker/middleware.py +389 -0
- truthound/checkpoint/circuitbreaker/registry.py +357 -0
- truthound/checkpoint/distributed/__init__.py +139 -0
- truthound/checkpoint/distributed/backends/__init__.py +35 -0
- truthound/checkpoint/distributed/backends/celery_backend.py +503 -0
- truthound/checkpoint/distributed/backends/kubernetes_backend.py +696 -0
- truthound/checkpoint/distributed/backends/local_backend.py +397 -0
- truthound/checkpoint/distributed/backends/ray_backend.py +625 -0
- truthound/checkpoint/distributed/base.py +774 -0
- truthound/checkpoint/distributed/orchestrator.py +765 -0
- truthound/checkpoint/distributed/protocols.py +842 -0
- truthound/checkpoint/distributed/registry.py +449 -0
- truthound/checkpoint/idempotency/__init__.py +120 -0
- truthound/checkpoint/idempotency/core.py +295 -0
- truthound/checkpoint/idempotency/fingerprint.py +454 -0
- truthound/checkpoint/idempotency/locking.py +604 -0
- truthound/checkpoint/idempotency/service.py +592 -0
- truthound/checkpoint/idempotency/stores.py +653 -0
- truthound/checkpoint/monitoring/__init__.py +134 -0
- truthound/checkpoint/monitoring/aggregators/__init__.py +15 -0
- truthound/checkpoint/monitoring/aggregators/base.py +372 -0
- truthound/checkpoint/monitoring/aggregators/realtime.py +300 -0
- truthound/checkpoint/monitoring/aggregators/window.py +493 -0
- truthound/checkpoint/monitoring/collectors/__init__.py +17 -0
- truthound/checkpoint/monitoring/collectors/base.py +257 -0
- truthound/checkpoint/monitoring/collectors/memory_collector.py +617 -0
- truthound/checkpoint/monitoring/collectors/prometheus_collector.py +451 -0
- truthound/checkpoint/monitoring/collectors/redis_collector.py +518 -0
- truthound/checkpoint/monitoring/events.py +410 -0
- truthound/checkpoint/monitoring/protocols.py +636 -0
- truthound/checkpoint/monitoring/service.py +578 -0
- truthound/checkpoint/monitoring/views/__init__.py +17 -0
- truthound/checkpoint/monitoring/views/base.py +172 -0
- truthound/checkpoint/monitoring/views/queue_view.py +220 -0
- truthound/checkpoint/monitoring/views/task_view.py +240 -0
- truthound/checkpoint/monitoring/views/worker_view.py +263 -0
- truthound/checkpoint/registry.py +337 -0
- truthound/checkpoint/runner.py +356 -0
- truthound/checkpoint/transaction/__init__.py +133 -0
- truthound/checkpoint/transaction/base.py +389 -0
- truthound/checkpoint/transaction/compensatable.py +537 -0
- truthound/checkpoint/transaction/coordinator.py +576 -0
- truthound/checkpoint/transaction/executor.py +622 -0
- truthound/checkpoint/transaction/idempotency.py +534 -0
- truthound/checkpoint/transaction/saga/__init__.py +143 -0
- truthound/checkpoint/transaction/saga/builder.py +584 -0
- truthound/checkpoint/transaction/saga/definition.py +515 -0
- truthound/checkpoint/transaction/saga/event_store.py +542 -0
- truthound/checkpoint/transaction/saga/patterns.py +833 -0
- truthound/checkpoint/transaction/saga/runner.py +718 -0
- truthound/checkpoint/transaction/saga/state_machine.py +793 -0
- truthound/checkpoint/transaction/saga/strategies.py +780 -0
- truthound/checkpoint/transaction/saga/testing.py +886 -0
- truthound/checkpoint/triggers/__init__.py +58 -0
- truthound/checkpoint/triggers/base.py +237 -0
- truthound/checkpoint/triggers/event.py +385 -0
- truthound/checkpoint/triggers/schedule.py +355 -0
- truthound/cli.py +2358 -0
- truthound/cli_modules/__init__.py +124 -0
- truthound/cli_modules/advanced/__init__.py +45 -0
- truthound/cli_modules/advanced/benchmark.py +343 -0
- truthound/cli_modules/advanced/docs.py +225 -0
- truthound/cli_modules/advanced/lineage.py +209 -0
- truthound/cli_modules/advanced/ml.py +320 -0
- truthound/cli_modules/advanced/realtime.py +196 -0
- truthound/cli_modules/checkpoint/__init__.py +46 -0
- truthound/cli_modules/checkpoint/init.py +114 -0
- truthound/cli_modules/checkpoint/list.py +71 -0
- truthound/cli_modules/checkpoint/run.py +159 -0
- truthound/cli_modules/checkpoint/validate.py +67 -0
- truthound/cli_modules/common/__init__.py +71 -0
- truthound/cli_modules/common/errors.py +414 -0
- truthound/cli_modules/common/options.py +419 -0
- truthound/cli_modules/common/output.py +507 -0
- truthound/cli_modules/common/protocol.py +552 -0
- truthound/cli_modules/core/__init__.py +48 -0
- truthound/cli_modules/core/check.py +123 -0
- truthound/cli_modules/core/compare.py +104 -0
- truthound/cli_modules/core/learn.py +57 -0
- truthound/cli_modules/core/mask.py +77 -0
- truthound/cli_modules/core/profile.py +65 -0
- truthound/cli_modules/core/scan.py +61 -0
- truthound/cli_modules/profiler/__init__.py +51 -0
- truthound/cli_modules/profiler/auto_profile.py +175 -0
- truthound/cli_modules/profiler/metadata.py +107 -0
- truthound/cli_modules/profiler/suite.py +283 -0
- truthound/cli_modules/registry.py +431 -0
- truthound/cli_modules/scaffolding/__init__.py +89 -0
- truthound/cli_modules/scaffolding/base.py +631 -0
- truthound/cli_modules/scaffolding/commands.py +545 -0
- truthound/cli_modules/scaffolding/plugins.py +1072 -0
- truthound/cli_modules/scaffolding/reporters.py +594 -0
- truthound/cli_modules/scaffolding/validators.py +1127 -0
- truthound/common/__init__.py +18 -0
- truthound/common/resilience/__init__.py +130 -0
- truthound/common/resilience/bulkhead.py +266 -0
- truthound/common/resilience/circuit_breaker.py +516 -0
- truthound/common/resilience/composite.py +332 -0
- truthound/common/resilience/config.py +292 -0
- truthound/common/resilience/protocols.py +217 -0
- truthound/common/resilience/rate_limiter.py +404 -0
- truthound/common/resilience/retry.py +341 -0
- truthound/datadocs/__init__.py +260 -0
- truthound/datadocs/base.py +571 -0
- truthound/datadocs/builder.py +761 -0
- truthound/datadocs/charts.py +764 -0
- truthound/datadocs/dashboard/__init__.py +63 -0
- truthound/datadocs/dashboard/app.py +576 -0
- truthound/datadocs/dashboard/components.py +584 -0
- truthound/datadocs/dashboard/state.py +240 -0
- truthound/datadocs/engine/__init__.py +46 -0
- truthound/datadocs/engine/context.py +376 -0
- truthound/datadocs/engine/pipeline.py +618 -0
- truthound/datadocs/engine/registry.py +469 -0
- truthound/datadocs/exporters/__init__.py +49 -0
- truthound/datadocs/exporters/base.py +198 -0
- truthound/datadocs/exporters/html.py +178 -0
- truthound/datadocs/exporters/json_exporter.py +253 -0
- truthound/datadocs/exporters/markdown.py +284 -0
- truthound/datadocs/exporters/pdf.py +392 -0
- truthound/datadocs/i18n/__init__.py +86 -0
- truthound/datadocs/i18n/catalog.py +960 -0
- truthound/datadocs/i18n/formatting.py +505 -0
- truthound/datadocs/i18n/loader.py +256 -0
- truthound/datadocs/i18n/plurals.py +378 -0
- truthound/datadocs/renderers/__init__.py +42 -0
- truthound/datadocs/renderers/base.py +401 -0
- truthound/datadocs/renderers/custom.py +342 -0
- truthound/datadocs/renderers/jinja.py +697 -0
- truthound/datadocs/sections.py +736 -0
- truthound/datadocs/styles.py +931 -0
- truthound/datadocs/themes/__init__.py +101 -0
- truthound/datadocs/themes/base.py +336 -0
- truthound/datadocs/themes/default.py +417 -0
- truthound/datadocs/themes/enterprise.py +419 -0
- truthound/datadocs/themes/loader.py +336 -0
- truthound/datadocs/themes.py +301 -0
- truthound/datadocs/transformers/__init__.py +57 -0
- truthound/datadocs/transformers/base.py +268 -0
- truthound/datadocs/transformers/enrichers.py +544 -0
- truthound/datadocs/transformers/filters.py +447 -0
- truthound/datadocs/transformers/i18n.py +468 -0
- truthound/datadocs/versioning/__init__.py +62 -0
- truthound/datadocs/versioning/diff.py +639 -0
- truthound/datadocs/versioning/storage.py +497 -0
- truthound/datadocs/versioning/version.py +358 -0
- truthound/datasources/__init__.py +223 -0
- truthound/datasources/_async_protocols.py +222 -0
- truthound/datasources/_protocols.py +159 -0
- truthound/datasources/adapters.py +428 -0
- truthound/datasources/async_base.py +599 -0
- truthound/datasources/async_factory.py +511 -0
- truthound/datasources/base.py +516 -0
- truthound/datasources/factory.py +433 -0
- truthound/datasources/nosql/__init__.py +47 -0
- truthound/datasources/nosql/base.py +487 -0
- truthound/datasources/nosql/elasticsearch.py +801 -0
- truthound/datasources/nosql/mongodb.py +636 -0
- truthound/datasources/pandas_optimized.py +582 -0
- truthound/datasources/pandas_source.py +216 -0
- truthound/datasources/polars_source.py +395 -0
- truthound/datasources/spark_source.py +479 -0
- truthound/datasources/sql/__init__.py +154 -0
- truthound/datasources/sql/base.py +710 -0
- truthound/datasources/sql/bigquery.py +410 -0
- truthound/datasources/sql/cloud_base.py +199 -0
- truthound/datasources/sql/databricks.py +471 -0
- truthound/datasources/sql/mysql.py +316 -0
- truthound/datasources/sql/oracle.py +427 -0
- truthound/datasources/sql/postgresql.py +321 -0
- truthound/datasources/sql/redshift.py +479 -0
- truthound/datasources/sql/snowflake.py +439 -0
- truthound/datasources/sql/sqlite.py +286 -0
- truthound/datasources/sql/sqlserver.py +437 -0
- truthound/datasources/streaming/__init__.py +47 -0
- truthound/datasources/streaming/base.py +350 -0
- truthound/datasources/streaming/kafka.py +670 -0
- truthound/decorators.py +98 -0
- truthound/docs/__init__.py +69 -0
- truthound/docs/extractor.py +971 -0
- truthound/docs/generator.py +601 -0
- truthound/docs/parser.py +1037 -0
- truthound/docs/renderer.py +999 -0
- truthound/drift/__init__.py +22 -0
- truthound/drift/compare.py +189 -0
- truthound/drift/detectors.py +464 -0
- truthound/drift/report.py +160 -0
- truthound/execution/__init__.py +65 -0
- truthound/execution/_protocols.py +324 -0
- truthound/execution/base.py +576 -0
- truthound/execution/distributed/__init__.py +179 -0
- truthound/execution/distributed/aggregations.py +731 -0
- truthound/execution/distributed/arrow_bridge.py +817 -0
- truthound/execution/distributed/base.py +550 -0
- truthound/execution/distributed/dask_engine.py +976 -0
- truthound/execution/distributed/mixins.py +766 -0
- truthound/execution/distributed/protocols.py +756 -0
- truthound/execution/distributed/ray_engine.py +1127 -0
- truthound/execution/distributed/registry.py +446 -0
- truthound/execution/distributed/spark_engine.py +1011 -0
- truthound/execution/distributed/validator_adapter.py +682 -0
- truthound/execution/pandas_engine.py +401 -0
- truthound/execution/polars_engine.py +497 -0
- truthound/execution/pushdown/__init__.py +230 -0
- truthound/execution/pushdown/ast.py +1550 -0
- truthound/execution/pushdown/builder.py +1550 -0
- truthound/execution/pushdown/dialects.py +1072 -0
- truthound/execution/pushdown/executor.py +829 -0
- truthound/execution/pushdown/optimizer.py +1041 -0
- truthound/execution/sql_engine.py +518 -0
- truthound/infrastructure/__init__.py +189 -0
- truthound/infrastructure/audit.py +1515 -0
- truthound/infrastructure/config.py +1133 -0
- truthound/infrastructure/encryption.py +1132 -0
- truthound/infrastructure/logging.py +1503 -0
- truthound/infrastructure/metrics.py +1220 -0
- truthound/lineage/__init__.py +89 -0
- truthound/lineage/base.py +746 -0
- truthound/lineage/impact_analysis.py +474 -0
- truthound/lineage/integrations/__init__.py +22 -0
- truthound/lineage/integrations/openlineage.py +548 -0
- truthound/lineage/tracker.py +512 -0
- truthound/lineage/visualization/__init__.py +33 -0
- truthound/lineage/visualization/protocols.py +145 -0
- truthound/lineage/visualization/renderers/__init__.py +20 -0
- truthound/lineage/visualization/renderers/cytoscape.py +329 -0
- truthound/lineage/visualization/renderers/d3.py +331 -0
- truthound/lineage/visualization/renderers/graphviz.py +276 -0
- truthound/lineage/visualization/renderers/mermaid.py +308 -0
- truthound/maskers.py +113 -0
- truthound/ml/__init__.py +124 -0
- truthound/ml/anomaly_models/__init__.py +31 -0
- truthound/ml/anomaly_models/ensemble.py +362 -0
- truthound/ml/anomaly_models/isolation_forest.py +444 -0
- truthound/ml/anomaly_models/statistical.py +392 -0
- truthound/ml/base.py +1178 -0
- truthound/ml/drift_detection/__init__.py +26 -0
- truthound/ml/drift_detection/concept.py +381 -0
- truthound/ml/drift_detection/distribution.py +361 -0
- truthound/ml/drift_detection/feature.py +442 -0
- truthound/ml/drift_detection/multivariate.py +495 -0
- truthound/ml/monitoring/__init__.py +88 -0
- truthound/ml/monitoring/alerting/__init__.py +33 -0
- truthound/ml/monitoring/alerting/handlers.py +427 -0
- truthound/ml/monitoring/alerting/rules.py +508 -0
- truthound/ml/monitoring/collectors/__init__.py +19 -0
- truthound/ml/monitoring/collectors/composite.py +105 -0
- truthound/ml/monitoring/collectors/drift.py +324 -0
- truthound/ml/monitoring/collectors/performance.py +179 -0
- truthound/ml/monitoring/collectors/quality.py +369 -0
- truthound/ml/monitoring/monitor.py +536 -0
- truthound/ml/monitoring/protocols.py +451 -0
- truthound/ml/monitoring/stores/__init__.py +15 -0
- truthound/ml/monitoring/stores/memory.py +201 -0
- truthound/ml/monitoring/stores/prometheus.py +296 -0
- truthound/ml/rule_learning/__init__.py +25 -0
- truthound/ml/rule_learning/constraint_miner.py +443 -0
- truthound/ml/rule_learning/pattern_learner.py +499 -0
- truthound/ml/rule_learning/profile_learner.py +462 -0
- truthound/multitenancy/__init__.py +326 -0
- truthound/multitenancy/core.py +852 -0
- truthound/multitenancy/integration.py +597 -0
- truthound/multitenancy/isolation.py +630 -0
- truthound/multitenancy/manager.py +770 -0
- truthound/multitenancy/middleware.py +765 -0
- truthound/multitenancy/quota.py +537 -0
- truthound/multitenancy/resolvers.py +603 -0
- truthound/multitenancy/storage.py +703 -0
- truthound/observability/__init__.py +307 -0
- truthound/observability/context.py +531 -0
- truthound/observability/instrumentation.py +611 -0
- truthound/observability/logging.py +887 -0
- truthound/observability/metrics.py +1157 -0
- truthound/observability/tracing/__init__.py +178 -0
- truthound/observability/tracing/baggage.py +310 -0
- truthound/observability/tracing/config.py +426 -0
- truthound/observability/tracing/exporter.py +787 -0
- truthound/observability/tracing/integration.py +1018 -0
- truthound/observability/tracing/otel/__init__.py +146 -0
- truthound/observability/tracing/otel/adapter.py +982 -0
- truthound/observability/tracing/otel/bridge.py +1177 -0
- truthound/observability/tracing/otel/compat.py +681 -0
- truthound/observability/tracing/otel/config.py +691 -0
- truthound/observability/tracing/otel/detection.py +327 -0
- truthound/observability/tracing/otel/protocols.py +426 -0
- truthound/observability/tracing/processor.py +561 -0
- truthound/observability/tracing/propagator.py +757 -0
- truthound/observability/tracing/provider.py +569 -0
- truthound/observability/tracing/resource.py +515 -0
- truthound/observability/tracing/sampler.py +487 -0
- truthound/observability/tracing/span.py +676 -0
- truthound/plugins/__init__.py +198 -0
- truthound/plugins/base.py +599 -0
- truthound/plugins/cli.py +680 -0
- truthound/plugins/dependencies/__init__.py +42 -0
- truthound/plugins/dependencies/graph.py +422 -0
- truthound/plugins/dependencies/resolver.py +417 -0
- truthound/plugins/discovery.py +379 -0
- truthound/plugins/docs/__init__.py +46 -0
- truthound/plugins/docs/extractor.py +444 -0
- truthound/plugins/docs/renderer.py +499 -0
- truthound/plugins/enterprise_manager.py +877 -0
- truthound/plugins/examples/__init__.py +19 -0
- truthound/plugins/examples/custom_validators.py +317 -0
- truthound/plugins/examples/slack_notifier.py +312 -0
- truthound/plugins/examples/xml_reporter.py +254 -0
- truthound/plugins/hooks.py +558 -0
- truthound/plugins/lifecycle/__init__.py +43 -0
- truthound/plugins/lifecycle/hot_reload.py +402 -0
- truthound/plugins/lifecycle/manager.py +371 -0
- truthound/plugins/manager.py +736 -0
- truthound/plugins/registry.py +338 -0
- truthound/plugins/security/__init__.py +93 -0
- truthound/plugins/security/exceptions.py +332 -0
- truthound/plugins/security/policies.py +348 -0
- truthound/plugins/security/protocols.py +643 -0
- truthound/plugins/security/sandbox/__init__.py +45 -0
- truthound/plugins/security/sandbox/context.py +158 -0
- truthound/plugins/security/sandbox/engines/__init__.py +19 -0
- truthound/plugins/security/sandbox/engines/container.py +379 -0
- truthound/plugins/security/sandbox/engines/noop.py +144 -0
- truthound/plugins/security/sandbox/engines/process.py +336 -0
- truthound/plugins/security/sandbox/factory.py +211 -0
- truthound/plugins/security/signing/__init__.py +57 -0
- truthound/plugins/security/signing/service.py +330 -0
- truthound/plugins/security/signing/trust_store.py +368 -0
- truthound/plugins/security/signing/verifier.py +459 -0
- truthound/plugins/versioning/__init__.py +41 -0
- truthound/plugins/versioning/constraints.py +297 -0
- truthound/plugins/versioning/resolver.py +329 -0
- truthound/profiler/__init__.py +1729 -0
- truthound/profiler/_lazy.py +452 -0
- truthound/profiler/ab_testing/__init__.py +80 -0
- truthound/profiler/ab_testing/analysis.py +449 -0
- truthound/profiler/ab_testing/base.py +257 -0
- truthound/profiler/ab_testing/experiment.py +395 -0
- truthound/profiler/ab_testing/tracking.py +368 -0
- truthound/profiler/auto_threshold.py +1170 -0
- truthound/profiler/base.py +579 -0
- truthound/profiler/cache_patterns.py +911 -0
- truthound/profiler/caching.py +1303 -0
- truthound/profiler/column_profiler.py +712 -0
- truthound/profiler/comparison.py +1007 -0
- truthound/profiler/custom_patterns.py +1170 -0
- truthound/profiler/dashboard/__init__.py +50 -0
- truthound/profiler/dashboard/app.py +476 -0
- truthound/profiler/dashboard/components.py +457 -0
- truthound/profiler/dashboard/config.py +72 -0
- truthound/profiler/distributed/__init__.py +83 -0
- truthound/profiler/distributed/base.py +281 -0
- truthound/profiler/distributed/dask_backend.py +498 -0
- truthound/profiler/distributed/local_backend.py +293 -0
- truthound/profiler/distributed/profiler.py +304 -0
- truthound/profiler/distributed/ray_backend.py +374 -0
- truthound/profiler/distributed/spark_backend.py +375 -0
- truthound/profiler/distributed.py +1366 -0
- truthound/profiler/enterprise_sampling.py +1065 -0
- truthound/profiler/errors.py +488 -0
- truthound/profiler/evolution/__init__.py +91 -0
- truthound/profiler/evolution/alerts.py +426 -0
- truthound/profiler/evolution/changes.py +206 -0
- truthound/profiler/evolution/compatibility.py +365 -0
- truthound/profiler/evolution/detector.py +372 -0
- truthound/profiler/evolution/protocols.py +121 -0
- truthound/profiler/generators/__init__.py +48 -0
- truthound/profiler/generators/base.py +384 -0
- truthound/profiler/generators/ml_rules.py +375 -0
- truthound/profiler/generators/pattern_rules.py +384 -0
- truthound/profiler/generators/schema_rules.py +267 -0
- truthound/profiler/generators/stats_rules.py +324 -0
- truthound/profiler/generators/suite_generator.py +857 -0
- truthound/profiler/i18n.py +1542 -0
- truthound/profiler/incremental.py +554 -0
- truthound/profiler/incremental_validation.py +1710 -0
- truthound/profiler/integration/__init__.py +73 -0
- truthound/profiler/integration/adapters.py +345 -0
- truthound/profiler/integration/context.py +371 -0
- truthound/profiler/integration/executor.py +527 -0
- truthound/profiler/integration/naming.py +75 -0
- truthound/profiler/integration/protocols.py +243 -0
- truthound/profiler/memory.py +1185 -0
- truthound/profiler/migration/__init__.py +60 -0
- truthound/profiler/migration/base.py +345 -0
- truthound/profiler/migration/manager.py +444 -0
- truthound/profiler/migration/v1_0_to_v1_1.py +484 -0
- truthound/profiler/ml/__init__.py +73 -0
- truthound/profiler/ml/base.py +244 -0
- truthound/profiler/ml/classifier.py +507 -0
- truthound/profiler/ml/feature_extraction.py +604 -0
- truthound/profiler/ml/pretrained.py +448 -0
- truthound/profiler/ml_inference.py +1276 -0
- truthound/profiler/native_patterns.py +815 -0
- truthound/profiler/observability.py +1184 -0
- truthound/profiler/process_timeout.py +1566 -0
- truthound/profiler/progress.py +568 -0
- truthound/profiler/progress_callbacks.py +1734 -0
- truthound/profiler/quality.py +1345 -0
- truthound/profiler/resilience.py +1180 -0
- truthound/profiler/sampled_matcher.py +794 -0
- truthound/profiler/sampling.py +1288 -0
- truthound/profiler/scheduling/__init__.py +82 -0
- truthound/profiler/scheduling/protocols.py +214 -0
- truthound/profiler/scheduling/scheduler.py +474 -0
- truthound/profiler/scheduling/storage.py +457 -0
- truthound/profiler/scheduling/triggers.py +449 -0
- truthound/profiler/schema.py +603 -0
- truthound/profiler/streaming.py +685 -0
- truthound/profiler/streaming_patterns.py +1354 -0
- truthound/profiler/suite_cli.py +625 -0
- truthound/profiler/suite_config.py +789 -0
- truthound/profiler/suite_export.py +1268 -0
- truthound/profiler/table_profiler.py +547 -0
- truthound/profiler/timeout.py +565 -0
- truthound/profiler/validation.py +1532 -0
- truthound/profiler/visualization/__init__.py +118 -0
- truthound/profiler/visualization/base.py +346 -0
- truthound/profiler/visualization/generator.py +1259 -0
- truthound/profiler/visualization/plotly_renderer.py +811 -0
- truthound/profiler/visualization/renderers.py +669 -0
- truthound/profiler/visualization/sections.py +540 -0
- truthound/profiler/visualization.py +2122 -0
- truthound/profiler/yaml_validation.py +1151 -0
- truthound/py.typed +0 -0
- truthound/ratelimit/__init__.py +248 -0
- truthound/ratelimit/algorithms.py +1108 -0
- truthound/ratelimit/core.py +573 -0
- truthound/ratelimit/integration.py +532 -0
- truthound/ratelimit/limiter.py +663 -0
- truthound/ratelimit/middleware.py +700 -0
- truthound/ratelimit/policy.py +792 -0
- truthound/ratelimit/storage.py +763 -0
- truthound/rbac/__init__.py +340 -0
- truthound/rbac/core.py +976 -0
- truthound/rbac/integration.py +760 -0
- truthound/rbac/manager.py +1052 -0
- truthound/rbac/middleware.py +842 -0
- truthound/rbac/policy.py +954 -0
- truthound/rbac/storage.py +878 -0
- truthound/realtime/__init__.py +141 -0
- truthound/realtime/adapters/__init__.py +43 -0
- truthound/realtime/adapters/base.py +533 -0
- truthound/realtime/adapters/kafka.py +487 -0
- truthound/realtime/adapters/kinesis.py +479 -0
- truthound/realtime/adapters/mock.py +243 -0
- truthound/realtime/base.py +553 -0
- truthound/realtime/factory.py +382 -0
- truthound/realtime/incremental.py +660 -0
- truthound/realtime/processing/__init__.py +67 -0
- truthound/realtime/processing/exactly_once.py +575 -0
- truthound/realtime/processing/state.py +547 -0
- truthound/realtime/processing/windows.py +647 -0
- truthound/realtime/protocols.py +569 -0
- truthound/realtime/streaming.py +605 -0
- truthound/realtime/testing/__init__.py +32 -0
- truthound/realtime/testing/containers.py +615 -0
- truthound/realtime/testing/fixtures.py +484 -0
- truthound/report.py +280 -0
- truthound/reporters/__init__.py +46 -0
- truthound/reporters/_protocols.py +30 -0
- truthound/reporters/base.py +324 -0
- truthound/reporters/ci/__init__.py +66 -0
- truthound/reporters/ci/azure.py +436 -0
- truthound/reporters/ci/base.py +509 -0
- truthound/reporters/ci/bitbucket.py +567 -0
- truthound/reporters/ci/circleci.py +547 -0
- truthound/reporters/ci/detection.py +364 -0
- truthound/reporters/ci/factory.py +182 -0
- truthound/reporters/ci/github.py +388 -0
- truthound/reporters/ci/gitlab.py +471 -0
- truthound/reporters/ci/jenkins.py +525 -0
- truthound/reporters/console_reporter.py +299 -0
- truthound/reporters/factory.py +211 -0
- truthound/reporters/html_reporter.py +524 -0
- truthound/reporters/json_reporter.py +256 -0
- truthound/reporters/markdown_reporter.py +280 -0
- truthound/reporters/sdk/__init__.py +174 -0
- truthound/reporters/sdk/builder.py +558 -0
- truthound/reporters/sdk/mixins.py +1150 -0
- truthound/reporters/sdk/schema.py +1493 -0
- truthound/reporters/sdk/templates.py +666 -0
- truthound/reporters/sdk/testing.py +968 -0
- truthound/scanners.py +170 -0
- truthound/scheduling/__init__.py +122 -0
- truthound/scheduling/cron.py +1136 -0
- truthound/scheduling/presets.py +212 -0
- truthound/schema.py +275 -0
- truthound/secrets/__init__.py +173 -0
- truthound/secrets/base.py +618 -0
- truthound/secrets/cloud.py +682 -0
- truthound/secrets/integration.py +507 -0
- truthound/secrets/manager.py +633 -0
- truthound/secrets/oidc/__init__.py +172 -0
- truthound/secrets/oidc/base.py +902 -0
- truthound/secrets/oidc/credential_provider.py +623 -0
- truthound/secrets/oidc/exchangers.py +1001 -0
- truthound/secrets/oidc/github/__init__.py +110 -0
- truthound/secrets/oidc/github/claims.py +718 -0
- truthound/secrets/oidc/github/enhanced_provider.py +693 -0
- truthound/secrets/oidc/github/trust_policy.py +742 -0
- truthound/secrets/oidc/github/verification.py +723 -0
- truthound/secrets/oidc/github/workflow.py +691 -0
- truthound/secrets/oidc/providers.py +825 -0
- truthound/secrets/providers.py +506 -0
- truthound/secrets/resolver.py +495 -0
- truthound/stores/__init__.py +177 -0
- truthound/stores/backends/__init__.py +18 -0
- truthound/stores/backends/_protocols.py +340 -0
- truthound/stores/backends/azure_blob.py +530 -0
- truthound/stores/backends/concurrent_filesystem.py +915 -0
- truthound/stores/backends/connection_pool.py +1365 -0
- truthound/stores/backends/database.py +743 -0
- truthound/stores/backends/filesystem.py +538 -0
- truthound/stores/backends/gcs.py +399 -0
- truthound/stores/backends/memory.py +354 -0
- truthound/stores/backends/s3.py +434 -0
- truthound/stores/backpressure/__init__.py +84 -0
- truthound/stores/backpressure/base.py +375 -0
- truthound/stores/backpressure/circuit_breaker.py +434 -0
- truthound/stores/backpressure/monitor.py +376 -0
- truthound/stores/backpressure/strategies.py +677 -0
- truthound/stores/base.py +551 -0
- truthound/stores/batching/__init__.py +65 -0
- truthound/stores/batching/base.py +305 -0
- truthound/stores/batching/buffer.py +370 -0
- truthound/stores/batching/store.py +248 -0
- truthound/stores/batching/writer.py +521 -0
- truthound/stores/caching/__init__.py +60 -0
- truthound/stores/caching/backends.py +684 -0
- truthound/stores/caching/base.py +356 -0
- truthound/stores/caching/store.py +305 -0
- truthound/stores/compression/__init__.py +193 -0
- truthound/stores/compression/adaptive.py +694 -0
- truthound/stores/compression/base.py +514 -0
- truthound/stores/compression/pipeline.py +868 -0
- truthound/stores/compression/providers.py +672 -0
- truthound/stores/compression/streaming.py +832 -0
- truthound/stores/concurrency/__init__.py +81 -0
- truthound/stores/concurrency/atomic.py +556 -0
- truthound/stores/concurrency/index.py +775 -0
- truthound/stores/concurrency/locks.py +576 -0
- truthound/stores/concurrency/manager.py +482 -0
- truthound/stores/encryption/__init__.py +297 -0
- truthound/stores/encryption/base.py +952 -0
- truthound/stores/encryption/keys.py +1191 -0
- truthound/stores/encryption/pipeline.py +903 -0
- truthound/stores/encryption/providers.py +953 -0
- truthound/stores/encryption/streaming.py +950 -0
- truthound/stores/expectations.py +227 -0
- truthound/stores/factory.py +246 -0
- truthound/stores/migration/__init__.py +75 -0
- truthound/stores/migration/base.py +480 -0
- truthound/stores/migration/manager.py +347 -0
- truthound/stores/migration/registry.py +382 -0
- truthound/stores/migration/store.py +559 -0
- truthound/stores/observability/__init__.py +106 -0
- truthound/stores/observability/audit.py +718 -0
- truthound/stores/observability/config.py +270 -0
- truthound/stores/observability/factory.py +208 -0
- truthound/stores/observability/metrics.py +636 -0
- truthound/stores/observability/protocols.py +410 -0
- truthound/stores/observability/store.py +570 -0
- truthound/stores/observability/tracing.py +784 -0
- truthound/stores/replication/__init__.py +76 -0
- truthound/stores/replication/base.py +260 -0
- truthound/stores/replication/monitor.py +269 -0
- truthound/stores/replication/store.py +439 -0
- truthound/stores/replication/syncer.py +391 -0
- truthound/stores/results.py +359 -0
- truthound/stores/retention/__init__.py +77 -0
- truthound/stores/retention/base.py +378 -0
- truthound/stores/retention/policies.py +621 -0
- truthound/stores/retention/scheduler.py +279 -0
- truthound/stores/retention/store.py +526 -0
- truthound/stores/streaming/__init__.py +138 -0
- truthound/stores/streaming/base.py +801 -0
- truthound/stores/streaming/database.py +984 -0
- truthound/stores/streaming/filesystem.py +719 -0
- truthound/stores/streaming/reader.py +629 -0
- truthound/stores/streaming/s3.py +843 -0
- truthound/stores/streaming/writer.py +790 -0
- truthound/stores/tiering/__init__.py +108 -0
- truthound/stores/tiering/base.py +462 -0
- truthound/stores/tiering/manager.py +249 -0
- truthound/stores/tiering/policies.py +692 -0
- truthound/stores/tiering/store.py +526 -0
- truthound/stores/versioning/__init__.py +56 -0
- truthound/stores/versioning/base.py +376 -0
- truthound/stores/versioning/store.py +660 -0
- truthound/stores/versioning/strategies.py +353 -0
- truthound/types.py +56 -0
- truthound/validators/__init__.py +774 -0
- truthound/validators/aggregate/__init__.py +27 -0
- truthound/validators/aggregate/central.py +116 -0
- truthound/validators/aggregate/extremes.py +116 -0
- truthound/validators/aggregate/spread.py +118 -0
- truthound/validators/aggregate/sum.py +64 -0
- truthound/validators/aggregate/type.py +78 -0
- truthound/validators/anomaly/__init__.py +93 -0
- truthound/validators/anomaly/base.py +431 -0
- truthound/validators/anomaly/ml_based.py +1190 -0
- truthound/validators/anomaly/multivariate.py +647 -0
- truthound/validators/anomaly/statistical.py +599 -0
- truthound/validators/base.py +1089 -0
- truthound/validators/business_rule/__init__.py +46 -0
- truthound/validators/business_rule/base.py +147 -0
- truthound/validators/business_rule/checksum.py +509 -0
- truthound/validators/business_rule/financial.py +526 -0
- truthound/validators/cache.py +733 -0
- truthound/validators/completeness/__init__.py +39 -0
- truthound/validators/completeness/conditional.py +73 -0
- truthound/validators/completeness/default.py +98 -0
- truthound/validators/completeness/empty.py +103 -0
- truthound/validators/completeness/nan.py +337 -0
- truthound/validators/completeness/null.py +152 -0
- truthound/validators/cross_table/__init__.py +17 -0
- truthound/validators/cross_table/aggregate.py +333 -0
- truthound/validators/cross_table/row_count.py +122 -0
- truthound/validators/datetime/__init__.py +29 -0
- truthound/validators/datetime/format.py +78 -0
- truthound/validators/datetime/freshness.py +269 -0
- truthound/validators/datetime/order.py +73 -0
- truthound/validators/datetime/parseable.py +185 -0
- truthound/validators/datetime/range.py +202 -0
- truthound/validators/datetime/timezone.py +69 -0
- truthound/validators/distribution/__init__.py +49 -0
- truthound/validators/distribution/distribution.py +128 -0
- truthound/validators/distribution/monotonic.py +119 -0
- truthound/validators/distribution/outlier.py +178 -0
- truthound/validators/distribution/quantile.py +80 -0
- truthound/validators/distribution/range.py +254 -0
- truthound/validators/distribution/set.py +125 -0
- truthound/validators/distribution/statistical.py +459 -0
- truthound/validators/drift/__init__.py +79 -0
- truthound/validators/drift/base.py +427 -0
- truthound/validators/drift/multi_feature.py +401 -0
- truthound/validators/drift/numeric.py +395 -0
- truthound/validators/drift/psi.py +446 -0
- truthound/validators/drift/statistical.py +510 -0
- truthound/validators/enterprise.py +1658 -0
- truthound/validators/geospatial/__init__.py +80 -0
- truthound/validators/geospatial/base.py +97 -0
- truthound/validators/geospatial/boundary.py +238 -0
- truthound/validators/geospatial/coordinate.py +351 -0
- truthound/validators/geospatial/distance.py +399 -0
- truthound/validators/geospatial/polygon.py +665 -0
- truthound/validators/i18n/__init__.py +308 -0
- truthound/validators/i18n/bidi.py +571 -0
- truthound/validators/i18n/catalogs.py +570 -0
- truthound/validators/i18n/dialects.py +763 -0
- truthound/validators/i18n/extended_catalogs.py +549 -0
- truthound/validators/i18n/formatting.py +1434 -0
- truthound/validators/i18n/loader.py +1020 -0
- truthound/validators/i18n/messages.py +521 -0
- truthound/validators/i18n/plural.py +683 -0
- truthound/validators/i18n/protocols.py +855 -0
- truthound/validators/i18n/tms.py +1162 -0
- truthound/validators/localization/__init__.py +53 -0
- truthound/validators/localization/base.py +122 -0
- truthound/validators/localization/chinese.py +362 -0
- truthound/validators/localization/japanese.py +275 -0
- truthound/validators/localization/korean.py +524 -0
- truthound/validators/memory/__init__.py +94 -0
- truthound/validators/memory/approximate_knn.py +506 -0
- truthound/validators/memory/base.py +547 -0
- truthound/validators/memory/sgd_online.py +719 -0
- truthound/validators/memory/streaming_ecdf.py +753 -0
- truthound/validators/ml_feature/__init__.py +54 -0
- truthound/validators/ml_feature/base.py +249 -0
- truthound/validators/ml_feature/correlation.py +299 -0
- truthound/validators/ml_feature/leakage.py +344 -0
- truthound/validators/ml_feature/null_impact.py +270 -0
- truthound/validators/ml_feature/scale.py +264 -0
- truthound/validators/multi_column/__init__.py +89 -0
- truthound/validators/multi_column/arithmetic.py +284 -0
- truthound/validators/multi_column/base.py +231 -0
- truthound/validators/multi_column/comparison.py +273 -0
- truthound/validators/multi_column/consistency.py +312 -0
- truthound/validators/multi_column/statistical.py +299 -0
- truthound/validators/optimization/__init__.py +164 -0
- truthound/validators/optimization/aggregation.py +563 -0
- truthound/validators/optimization/covariance.py +556 -0
- truthound/validators/optimization/geo.py +626 -0
- truthound/validators/optimization/graph.py +587 -0
- truthound/validators/optimization/orchestrator.py +970 -0
- truthound/validators/optimization/profiling.py +1312 -0
- truthound/validators/privacy/__init__.py +223 -0
- truthound/validators/privacy/base.py +635 -0
- truthound/validators/privacy/ccpa.py +670 -0
- truthound/validators/privacy/gdpr.py +728 -0
- truthound/validators/privacy/global_patterns.py +604 -0
- truthound/validators/privacy/plugins.py +867 -0
- truthound/validators/profiling/__init__.py +52 -0
- truthound/validators/profiling/base.py +175 -0
- truthound/validators/profiling/cardinality.py +312 -0
- truthound/validators/profiling/entropy.py +391 -0
- truthound/validators/profiling/frequency.py +455 -0
- truthound/validators/pushdown_support.py +660 -0
- truthound/validators/query/__init__.py +91 -0
- truthound/validators/query/aggregate.py +346 -0
- truthound/validators/query/base.py +246 -0
- truthound/validators/query/column.py +249 -0
- truthound/validators/query/expression.py +274 -0
- truthound/validators/query/result.py +323 -0
- truthound/validators/query/row_count.py +264 -0
- truthound/validators/referential/__init__.py +80 -0
- truthound/validators/referential/base.py +395 -0
- truthound/validators/referential/cascade.py +391 -0
- truthound/validators/referential/circular.py +563 -0
- truthound/validators/referential/foreign_key.py +624 -0
- truthound/validators/referential/orphan.py +485 -0
- truthound/validators/registry.py +112 -0
- truthound/validators/schema/__init__.py +41 -0
- truthound/validators/schema/column_count.py +142 -0
- truthound/validators/schema/column_exists.py +80 -0
- truthound/validators/schema/column_order.py +82 -0
- truthound/validators/schema/column_pair.py +85 -0
- truthound/validators/schema/column_pair_set.py +195 -0
- truthound/validators/schema/column_type.py +94 -0
- truthound/validators/schema/multi_column.py +53 -0
- truthound/validators/schema/multi_column_aggregate.py +175 -0
- truthound/validators/schema/referential.py +274 -0
- truthound/validators/schema/table_schema.py +91 -0
- truthound/validators/schema_validator.py +219 -0
- truthound/validators/sdk/__init__.py +250 -0
- truthound/validators/sdk/builder.py +680 -0
- truthound/validators/sdk/decorators.py +474 -0
- truthound/validators/sdk/enterprise/__init__.py +211 -0
- truthound/validators/sdk/enterprise/docs.py +725 -0
- truthound/validators/sdk/enterprise/fuzzing.py +659 -0
- truthound/validators/sdk/enterprise/licensing.py +709 -0
- truthound/validators/sdk/enterprise/manager.py +543 -0
- truthound/validators/sdk/enterprise/resources.py +628 -0
- truthound/validators/sdk/enterprise/sandbox.py +766 -0
- truthound/validators/sdk/enterprise/signing.py +603 -0
- truthound/validators/sdk/enterprise/templates.py +865 -0
- truthound/validators/sdk/enterprise/versioning.py +659 -0
- truthound/validators/sdk/templates.py +757 -0
- truthound/validators/sdk/testing.py +807 -0
- truthound/validators/security/__init__.py +181 -0
- truthound/validators/security/redos/__init__.py +182 -0
- truthound/validators/security/redos/core.py +861 -0
- truthound/validators/security/redos/cpu_monitor.py +593 -0
- truthound/validators/security/redos/cve_database.py +791 -0
- truthound/validators/security/redos/ml/__init__.py +155 -0
- truthound/validators/security/redos/ml/base.py +785 -0
- truthound/validators/security/redos/ml/datasets.py +618 -0
- truthound/validators/security/redos/ml/features.py +359 -0
- truthound/validators/security/redos/ml/models.py +1000 -0
- truthound/validators/security/redos/ml/predictor.py +507 -0
- truthound/validators/security/redos/ml/storage.py +632 -0
- truthound/validators/security/redos/ml/training.py +571 -0
- truthound/validators/security/redos/ml_analyzer.py +937 -0
- truthound/validators/security/redos/optimizer.py +674 -0
- truthound/validators/security/redos/profiler.py +682 -0
- truthound/validators/security/redos/re2_engine.py +709 -0
- truthound/validators/security/redos.py +886 -0
- truthound/validators/security/sql_security.py +1247 -0
- truthound/validators/streaming/__init__.py +126 -0
- truthound/validators/streaming/base.py +292 -0
- truthound/validators/streaming/completeness.py +210 -0
- truthound/validators/streaming/mixin.py +575 -0
- truthound/validators/streaming/range.py +308 -0
- truthound/validators/streaming/sources.py +846 -0
- truthound/validators/string/__init__.py +57 -0
- truthound/validators/string/casing.py +158 -0
- truthound/validators/string/charset.py +96 -0
- truthound/validators/string/format.py +501 -0
- truthound/validators/string/json.py +77 -0
- truthound/validators/string/json_schema.py +184 -0
- truthound/validators/string/length.py +104 -0
- truthound/validators/string/like_pattern.py +237 -0
- truthound/validators/string/regex.py +202 -0
- truthound/validators/string/regex_extended.py +435 -0
- truthound/validators/table/__init__.py +88 -0
- truthound/validators/table/base.py +78 -0
- truthound/validators/table/column_count.py +198 -0
- truthound/validators/table/freshness.py +362 -0
- truthound/validators/table/row_count.py +251 -0
- truthound/validators/table/schema.py +333 -0
- truthound/validators/table/size.py +285 -0
- truthound/validators/timeout/__init__.py +102 -0
- truthound/validators/timeout/advanced/__init__.py +247 -0
- truthound/validators/timeout/advanced/circuit_breaker.py +675 -0
- truthound/validators/timeout/advanced/prediction.py +773 -0
- truthound/validators/timeout/advanced/priority.py +618 -0
- truthound/validators/timeout/advanced/redis_backend.py +770 -0
- truthound/validators/timeout/advanced/retry.py +721 -0
- truthound/validators/timeout/advanced/sampling.py +788 -0
- truthound/validators/timeout/advanced/sla.py +661 -0
- truthound/validators/timeout/advanced/telemetry.py +804 -0
- truthound/validators/timeout/cascade.py +477 -0
- truthound/validators/timeout/deadline.py +657 -0
- truthound/validators/timeout/degradation.py +525 -0
- truthound/validators/timeout/distributed.py +597 -0
- truthound/validators/timeseries/__init__.py +89 -0
- truthound/validators/timeseries/base.py +326 -0
- truthound/validators/timeseries/completeness.py +617 -0
- truthound/validators/timeseries/gap.py +485 -0
- truthound/validators/timeseries/monotonic.py +310 -0
- truthound/validators/timeseries/seasonality.py +422 -0
- truthound/validators/timeseries/trend.py +510 -0
- truthound/validators/uniqueness/__init__.py +59 -0
- truthound/validators/uniqueness/approximate.py +475 -0
- truthound/validators/uniqueness/distinct_values.py +253 -0
- truthound/validators/uniqueness/duplicate.py +118 -0
- truthound/validators/uniqueness/primary_key.py +140 -0
- truthound/validators/uniqueness/unique.py +191 -0
- truthound/validators/uniqueness/within_record.py +599 -0
- truthound/validators/utils.py +756 -0
- truthound-1.0.8.dist-info/METADATA +474 -0
- truthound-1.0.8.dist-info/RECORD +877 -0
- truthound-1.0.8.dist-info/WHEEL +4 -0
- truthound-1.0.8.dist-info/entry_points.txt +2 -0
- truthound-1.0.8.dist-info/licenses/LICENSE +190 -0
truthound/stores/base.py
ADDED
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
"""Base classes and interfaces for validation stores.
|
|
2
|
+
|
|
3
|
+
This module defines the abstract base classes and protocols that all store
|
|
4
|
+
implementations must follow. The design follows the Repository pattern with
|
|
5
|
+
a focus on extensibility and testability.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from abc import ABC, abstractmethod
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
from typing import (
|
|
14
|
+
TYPE_CHECKING,
|
|
15
|
+
Any,
|
|
16
|
+
Generic,
|
|
17
|
+
Iterator,
|
|
18
|
+
Protocol,
|
|
19
|
+
TypeVar,
|
|
20
|
+
runtime_checkable,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from truthound.stores.results import ValidationResult
|
|
25
|
+
from truthound.stores.expectations import ExpectationSuite
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# =============================================================================
|
|
29
|
+
# Exceptions
|
|
30
|
+
# =============================================================================
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class StoreError(Exception):
|
|
34
|
+
"""Base exception for all store-related errors."""
|
|
35
|
+
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class StoreNotFoundError(StoreError):
|
|
40
|
+
"""Raised when a requested item is not found in the store."""
|
|
41
|
+
|
|
42
|
+
def __init__(self, item_type: str, identifier: str) -> None:
|
|
43
|
+
self.item_type = item_type
|
|
44
|
+
self.identifier = identifier
|
|
45
|
+
super().__init__(f"{item_type} not found: {identifier}")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class StoreConnectionError(StoreError):
|
|
49
|
+
"""Raised when connection to store backend fails."""
|
|
50
|
+
|
|
51
|
+
def __init__(self, backend: str, message: str) -> None:
|
|
52
|
+
self.backend = backend
|
|
53
|
+
super().__init__(f"Failed to connect to {backend}: {message}")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class StoreWriteError(StoreError):
|
|
57
|
+
"""Raised when writing to store fails."""
|
|
58
|
+
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class StoreReadError(StoreError):
|
|
63
|
+
"""Raised when reading from store fails."""
|
|
64
|
+
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# =============================================================================
|
|
69
|
+
# Configuration
|
|
70
|
+
# =============================================================================
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclass
|
|
74
|
+
class StoreConfig:
|
|
75
|
+
"""Base configuration for all stores.
|
|
76
|
+
|
|
77
|
+
Subclasses can extend this with backend-specific options.
|
|
78
|
+
|
|
79
|
+
Attributes:
|
|
80
|
+
namespace: Optional namespace to isolate different projects/environments.
|
|
81
|
+
prefix: Path prefix for organizing stored data.
|
|
82
|
+
serialization_format: Format for serializing data ("json", "yaml", "pickle").
|
|
83
|
+
compression: Optional compression ("gzip", "zstd", None).
|
|
84
|
+
metadata: Additional metadata to include with stored items.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
namespace: str = "default"
|
|
88
|
+
prefix: str = ""
|
|
89
|
+
serialization_format: str = "json"
|
|
90
|
+
compression: str | None = None
|
|
91
|
+
metadata: dict[str, Any] = field(default_factory=dict)
|
|
92
|
+
|
|
93
|
+
def get_full_prefix(self) -> str:
|
|
94
|
+
"""Get the full path prefix including namespace."""
|
|
95
|
+
parts = [p for p in [self.namespace, self.prefix] if p]
|
|
96
|
+
return "/".join(parts)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# =============================================================================
|
|
100
|
+
# Protocols (Structural Typing)
|
|
101
|
+
# =============================================================================
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@runtime_checkable
|
|
105
|
+
class Serializable(Protocol):
|
|
106
|
+
"""Protocol for objects that can be serialized to/from dict."""
|
|
107
|
+
|
|
108
|
+
def to_dict(self) -> dict[str, Any]: ...
|
|
109
|
+
|
|
110
|
+
@classmethod
|
|
111
|
+
def from_dict(cls, data: dict[str, Any]) -> "Serializable": ...
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@runtime_checkable
|
|
115
|
+
class Identifiable(Protocol):
|
|
116
|
+
"""Protocol for objects with a unique identifier."""
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def id(self) -> str: ...
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# =============================================================================
|
|
123
|
+
# Type Variables
|
|
124
|
+
# =============================================================================
|
|
125
|
+
|
|
126
|
+
T = TypeVar("T", bound=Serializable)
|
|
127
|
+
ConfigT = TypeVar("ConfigT", bound=StoreConfig)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
# =============================================================================
|
|
131
|
+
# Query and Filter Classes
|
|
132
|
+
# =============================================================================
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@dataclass
|
|
136
|
+
class StoreQuery:
|
|
137
|
+
"""Query parameters for filtering stored items.
|
|
138
|
+
|
|
139
|
+
Attributes:
|
|
140
|
+
data_asset: Filter by data asset name (exact or pattern).
|
|
141
|
+
start_time: Filter results after this time.
|
|
142
|
+
end_time: Filter results before this time.
|
|
143
|
+
status: Filter by result status ("success", "failure", "error").
|
|
144
|
+
tags: Filter by tags (all must match).
|
|
145
|
+
limit: Maximum number of results to return.
|
|
146
|
+
offset: Number of results to skip (for pagination).
|
|
147
|
+
order_by: Field to order by ("run_time", "data_asset", "status").
|
|
148
|
+
ascending: Sort order (True for ascending, False for descending).
|
|
149
|
+
"""
|
|
150
|
+
|
|
151
|
+
data_asset: str | None = None
|
|
152
|
+
start_time: datetime | None = None
|
|
153
|
+
end_time: datetime | None = None
|
|
154
|
+
status: str | None = None
|
|
155
|
+
tags: dict[str, str] | None = None
|
|
156
|
+
limit: int | None = None
|
|
157
|
+
offset: int = 0
|
|
158
|
+
order_by: str = "run_time"
|
|
159
|
+
ascending: bool = False
|
|
160
|
+
|
|
161
|
+
def matches(self, item: dict[str, Any]) -> bool:
|
|
162
|
+
"""Check if an item matches this query's filters."""
|
|
163
|
+
if self.data_asset and item.get("data_asset") != self.data_asset:
|
|
164
|
+
return False
|
|
165
|
+
|
|
166
|
+
if self.status and item.get("status") != self.status:
|
|
167
|
+
return False
|
|
168
|
+
|
|
169
|
+
run_time = item.get("run_time")
|
|
170
|
+
if run_time:
|
|
171
|
+
if isinstance(run_time, str):
|
|
172
|
+
run_time = datetime.fromisoformat(run_time)
|
|
173
|
+
if self.start_time and run_time < self.start_time:
|
|
174
|
+
return False
|
|
175
|
+
if self.end_time and run_time > self.end_time:
|
|
176
|
+
return False
|
|
177
|
+
|
|
178
|
+
if self.tags:
|
|
179
|
+
item_tags = item.get("tags", {})
|
|
180
|
+
for key, value in self.tags.items():
|
|
181
|
+
if item_tags.get(key) != value:
|
|
182
|
+
return False
|
|
183
|
+
|
|
184
|
+
return True
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
# =============================================================================
|
|
188
|
+
# Abstract Base Store
|
|
189
|
+
# =============================================================================
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class BaseStore(ABC, Generic[T, ConfigT]):
|
|
193
|
+
"""Abstract base class for all validation stores.
|
|
194
|
+
|
|
195
|
+
This class defines the interface that all store implementations must follow.
|
|
196
|
+
It uses generics to allow type-safe operations with different stored types.
|
|
197
|
+
|
|
198
|
+
Type Parameters:
|
|
199
|
+
T: The type of objects being stored (must be Serializable).
|
|
200
|
+
ConfigT: The configuration type for this store.
|
|
201
|
+
|
|
202
|
+
Example:
|
|
203
|
+
>>> class MyStore(BaseStore[ValidationResult, MyStoreConfig]):
|
|
204
|
+
... def save(self, item: ValidationResult) -> str:
|
|
205
|
+
... # Implementation
|
|
206
|
+
... pass
|
|
207
|
+
"""
|
|
208
|
+
|
|
209
|
+
def __init__(self, config: ConfigT | None = None) -> None:
|
|
210
|
+
"""Initialize the store with optional configuration.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
config: Store configuration. If None, uses default configuration.
|
|
214
|
+
"""
|
|
215
|
+
self._config = config or self._default_config()
|
|
216
|
+
self._initialized = False
|
|
217
|
+
|
|
218
|
+
@classmethod
|
|
219
|
+
@abstractmethod
|
|
220
|
+
def _default_config(cls) -> ConfigT:
|
|
221
|
+
"""Create default configuration for this store type."""
|
|
222
|
+
pass
|
|
223
|
+
|
|
224
|
+
@property
|
|
225
|
+
def config(self) -> ConfigT:
|
|
226
|
+
"""Get the store configuration."""
|
|
227
|
+
return self._config
|
|
228
|
+
|
|
229
|
+
# -------------------------------------------------------------------------
|
|
230
|
+
# Lifecycle Methods
|
|
231
|
+
# -------------------------------------------------------------------------
|
|
232
|
+
|
|
233
|
+
def initialize(self) -> None:
|
|
234
|
+
"""Initialize the store (create directories, connect to database, etc.).
|
|
235
|
+
|
|
236
|
+
This method is called automatically on first use, but can be called
|
|
237
|
+
explicitly for early initialization or connection testing.
|
|
238
|
+
"""
|
|
239
|
+
if not self._initialized:
|
|
240
|
+
self._do_initialize()
|
|
241
|
+
self._initialized = True
|
|
242
|
+
|
|
243
|
+
@abstractmethod
|
|
244
|
+
def _do_initialize(self) -> None:
|
|
245
|
+
"""Perform actual initialization. Override in subclasses."""
|
|
246
|
+
pass
|
|
247
|
+
|
|
248
|
+
def close(self) -> None:
|
|
249
|
+
"""Close any open connections or resources.
|
|
250
|
+
|
|
251
|
+
Override in subclasses that need cleanup (e.g., database connections).
|
|
252
|
+
"""
|
|
253
|
+
pass
|
|
254
|
+
|
|
255
|
+
def __enter__(self) -> "BaseStore[T, ConfigT]":
|
|
256
|
+
"""Context manager entry."""
|
|
257
|
+
self.initialize()
|
|
258
|
+
return self
|
|
259
|
+
|
|
260
|
+
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
261
|
+
"""Context manager exit."""
|
|
262
|
+
self.close()
|
|
263
|
+
|
|
264
|
+
# -------------------------------------------------------------------------
|
|
265
|
+
# CRUD Operations
|
|
266
|
+
# -------------------------------------------------------------------------
|
|
267
|
+
|
|
268
|
+
@abstractmethod
|
|
269
|
+
def save(self, item: T) -> str:
|
|
270
|
+
"""Save an item to the store.
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
item: The item to save.
|
|
274
|
+
|
|
275
|
+
Returns:
|
|
276
|
+
The unique identifier for the saved item.
|
|
277
|
+
|
|
278
|
+
Raises:
|
|
279
|
+
StoreWriteError: If saving fails.
|
|
280
|
+
"""
|
|
281
|
+
pass
|
|
282
|
+
|
|
283
|
+
@abstractmethod
|
|
284
|
+
def get(self, item_id: str) -> T:
|
|
285
|
+
"""Retrieve an item by its identifier.
|
|
286
|
+
|
|
287
|
+
Args:
|
|
288
|
+
item_id: The unique identifier of the item.
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
The retrieved item.
|
|
292
|
+
|
|
293
|
+
Raises:
|
|
294
|
+
StoreNotFoundError: If the item doesn't exist.
|
|
295
|
+
StoreReadError: If reading fails.
|
|
296
|
+
"""
|
|
297
|
+
pass
|
|
298
|
+
|
|
299
|
+
@abstractmethod
|
|
300
|
+
def exists(self, item_id: str) -> bool:
|
|
301
|
+
"""Check if an item exists in the store.
|
|
302
|
+
|
|
303
|
+
Args:
|
|
304
|
+
item_id: The unique identifier to check.
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
True if the item exists, False otherwise.
|
|
308
|
+
"""
|
|
309
|
+
pass
|
|
310
|
+
|
|
311
|
+
@abstractmethod
|
|
312
|
+
def delete(self, item_id: str) -> bool:
|
|
313
|
+
"""Delete an item from the store.
|
|
314
|
+
|
|
315
|
+
Args:
|
|
316
|
+
item_id: The unique identifier of the item to delete.
|
|
317
|
+
|
|
318
|
+
Returns:
|
|
319
|
+
True if the item was deleted, False if it didn't exist.
|
|
320
|
+
|
|
321
|
+
Raises:
|
|
322
|
+
StoreWriteError: If deletion fails.
|
|
323
|
+
"""
|
|
324
|
+
pass
|
|
325
|
+
|
|
326
|
+
# -------------------------------------------------------------------------
|
|
327
|
+
# Query Operations
|
|
328
|
+
# -------------------------------------------------------------------------
|
|
329
|
+
|
|
330
|
+
@abstractmethod
|
|
331
|
+
def list_ids(self, query: StoreQuery | None = None) -> list[str]:
|
|
332
|
+
"""List item identifiers matching the query.
|
|
333
|
+
|
|
334
|
+
Args:
|
|
335
|
+
query: Optional query to filter results.
|
|
336
|
+
|
|
337
|
+
Returns:
|
|
338
|
+
List of matching item identifiers.
|
|
339
|
+
"""
|
|
340
|
+
pass
|
|
341
|
+
|
|
342
|
+
@abstractmethod
|
|
343
|
+
def query(self, query: StoreQuery) -> list[T]:
|
|
344
|
+
"""Query items matching the given criteria.
|
|
345
|
+
|
|
346
|
+
Args:
|
|
347
|
+
query: Query parameters for filtering.
|
|
348
|
+
|
|
349
|
+
Returns:
|
|
350
|
+
List of matching items.
|
|
351
|
+
"""
|
|
352
|
+
pass
|
|
353
|
+
|
|
354
|
+
def iter_query(self, query: StoreQuery, batch_size: int = 100) -> Iterator[T]:
|
|
355
|
+
"""Iterate over items matching the query in batches.
|
|
356
|
+
|
|
357
|
+
This is more memory-efficient for large result sets.
|
|
358
|
+
|
|
359
|
+
Args:
|
|
360
|
+
query: Query parameters for filtering.
|
|
361
|
+
batch_size: Number of items to fetch per batch.
|
|
362
|
+
|
|
363
|
+
Yields:
|
|
364
|
+
Items matching the query.
|
|
365
|
+
"""
|
|
366
|
+
offset = query.offset
|
|
367
|
+
while True:
|
|
368
|
+
batch_query = StoreQuery(
|
|
369
|
+
data_asset=query.data_asset,
|
|
370
|
+
start_time=query.start_time,
|
|
371
|
+
end_time=query.end_time,
|
|
372
|
+
status=query.status,
|
|
373
|
+
tags=query.tags,
|
|
374
|
+
limit=batch_size,
|
|
375
|
+
offset=offset,
|
|
376
|
+
order_by=query.order_by,
|
|
377
|
+
ascending=query.ascending,
|
|
378
|
+
)
|
|
379
|
+
batch = self.query(batch_query)
|
|
380
|
+
if not batch:
|
|
381
|
+
break
|
|
382
|
+
yield from batch
|
|
383
|
+
offset += len(batch)
|
|
384
|
+
if query.limit and offset >= query.offset + query.limit:
|
|
385
|
+
break
|
|
386
|
+
|
|
387
|
+
# -------------------------------------------------------------------------
|
|
388
|
+
# Convenience Methods
|
|
389
|
+
# -------------------------------------------------------------------------
|
|
390
|
+
|
|
391
|
+
def get_latest(self, data_asset: str) -> T | None:
|
|
392
|
+
"""Get the most recent item for a data asset.
|
|
393
|
+
|
|
394
|
+
Args:
|
|
395
|
+
data_asset: The data asset to get the latest result for.
|
|
396
|
+
|
|
397
|
+
Returns:
|
|
398
|
+
The latest item, or None if no items exist.
|
|
399
|
+
"""
|
|
400
|
+
query = StoreQuery(
|
|
401
|
+
data_asset=data_asset,
|
|
402
|
+
limit=1,
|
|
403
|
+
order_by="run_time",
|
|
404
|
+
ascending=False,
|
|
405
|
+
)
|
|
406
|
+
results = self.query(query)
|
|
407
|
+
return results[0] if results else None
|
|
408
|
+
|
|
409
|
+
def count(self, query: StoreQuery | None = None) -> int:
|
|
410
|
+
"""Count items matching the query.
|
|
411
|
+
|
|
412
|
+
Args:
|
|
413
|
+
query: Optional query to filter items.
|
|
414
|
+
|
|
415
|
+
Returns:
|
|
416
|
+
Number of matching items.
|
|
417
|
+
"""
|
|
418
|
+
return len(self.list_ids(query))
|
|
419
|
+
|
|
420
|
+
def clear(self, query: StoreQuery | None = None) -> int:
|
|
421
|
+
"""Delete all items matching the query.
|
|
422
|
+
|
|
423
|
+
Args:
|
|
424
|
+
query: Optional query to filter items. If None, deletes all items.
|
|
425
|
+
|
|
426
|
+
Returns:
|
|
427
|
+
Number of items deleted.
|
|
428
|
+
"""
|
|
429
|
+
ids = self.list_ids(query)
|
|
430
|
+
deleted = 0
|
|
431
|
+
for item_id in ids:
|
|
432
|
+
if self.delete(item_id):
|
|
433
|
+
deleted += 1
|
|
434
|
+
return deleted
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
# =============================================================================
|
|
438
|
+
# Specialized Store Types
|
|
439
|
+
# =============================================================================
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
class ValidationStore(BaseStore["ValidationResult", ConfigT], Generic[ConfigT]):
|
|
443
|
+
"""Store specialized for validation results.
|
|
444
|
+
|
|
445
|
+
Provides additional methods specific to validation result storage.
|
|
446
|
+
"""
|
|
447
|
+
|
|
448
|
+
def list_runs(self, data_asset: str) -> list[str]:
|
|
449
|
+
"""List all run IDs for a data asset.
|
|
450
|
+
|
|
451
|
+
Args:
|
|
452
|
+
data_asset: The data asset to list runs for.
|
|
453
|
+
|
|
454
|
+
Returns:
|
|
455
|
+
List of run IDs, ordered by time (newest first).
|
|
456
|
+
"""
|
|
457
|
+
query = StoreQuery(
|
|
458
|
+
data_asset=data_asset,
|
|
459
|
+
order_by="run_time",
|
|
460
|
+
ascending=False,
|
|
461
|
+
)
|
|
462
|
+
return self.list_ids(query)
|
|
463
|
+
|
|
464
|
+
def get_history(
|
|
465
|
+
self,
|
|
466
|
+
data_asset: str,
|
|
467
|
+
limit: int = 10,
|
|
468
|
+
) -> list["ValidationResult"]:
|
|
469
|
+
"""Get validation history for a data asset.
|
|
470
|
+
|
|
471
|
+
Args:
|
|
472
|
+
data_asset: The data asset to get history for.
|
|
473
|
+
limit: Maximum number of results to return.
|
|
474
|
+
|
|
475
|
+
Returns:
|
|
476
|
+
List of validation results, ordered by time (newest first).
|
|
477
|
+
"""
|
|
478
|
+
query = StoreQuery(
|
|
479
|
+
data_asset=data_asset,
|
|
480
|
+
limit=limit,
|
|
481
|
+
order_by="run_time",
|
|
482
|
+
ascending=False,
|
|
483
|
+
)
|
|
484
|
+
return self.query(query)
|
|
485
|
+
|
|
486
|
+
def get_failures(
|
|
487
|
+
self,
|
|
488
|
+
data_asset: str | None = None,
|
|
489
|
+
limit: int = 100,
|
|
490
|
+
) -> list["ValidationResult"]:
|
|
491
|
+
"""Get failed validation results.
|
|
492
|
+
|
|
493
|
+
Args:
|
|
494
|
+
data_asset: Optional data asset to filter by.
|
|
495
|
+
limit: Maximum number of results to return.
|
|
496
|
+
|
|
497
|
+
Returns:
|
|
498
|
+
List of failed validation results.
|
|
499
|
+
"""
|
|
500
|
+
query = StoreQuery(
|
|
501
|
+
data_asset=data_asset,
|
|
502
|
+
status="failure",
|
|
503
|
+
limit=limit,
|
|
504
|
+
order_by="run_time",
|
|
505
|
+
ascending=False,
|
|
506
|
+
)
|
|
507
|
+
return self.query(query)
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
class ExpectationStore(BaseStore["ExpectationSuite", ConfigT], Generic[ConfigT]):
|
|
511
|
+
"""Store specialized for expectation suites.
|
|
512
|
+
|
|
513
|
+
Provides additional methods specific to expectation storage.
|
|
514
|
+
"""
|
|
515
|
+
|
|
516
|
+
def list_suites(self, data_asset: str | None = None) -> list[str]:
|
|
517
|
+
"""List all expectation suite names.
|
|
518
|
+
|
|
519
|
+
Args:
|
|
520
|
+
data_asset: Optional data asset to filter by.
|
|
521
|
+
|
|
522
|
+
Returns:
|
|
523
|
+
List of suite names.
|
|
524
|
+
"""
|
|
525
|
+
query = StoreQuery(data_asset=data_asset) if data_asset else None
|
|
526
|
+
return self.list_ids(query)
|
|
527
|
+
|
|
528
|
+
def get_suite(self, suite_name: str) -> "ExpectationSuite":
|
|
529
|
+
"""Get an expectation suite by name.
|
|
530
|
+
|
|
531
|
+
Args:
|
|
532
|
+
suite_name: The name of the suite to retrieve.
|
|
533
|
+
|
|
534
|
+
Returns:
|
|
535
|
+
The expectation suite.
|
|
536
|
+
|
|
537
|
+
Raises:
|
|
538
|
+
StoreNotFoundError: If the suite doesn't exist.
|
|
539
|
+
"""
|
|
540
|
+
return self.get(suite_name)
|
|
541
|
+
|
|
542
|
+
def save_suite(self, suite: "ExpectationSuite") -> str:
|
|
543
|
+
"""Save an expectation suite.
|
|
544
|
+
|
|
545
|
+
Args:
|
|
546
|
+
suite: The suite to save.
|
|
547
|
+
|
|
548
|
+
Returns:
|
|
549
|
+
The suite name.
|
|
550
|
+
"""
|
|
551
|
+
return self.save(suite)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""Batch write optimization for storage operations.
|
|
2
|
+
|
|
3
|
+
This module provides batch writing capabilities to optimize throughput
|
|
4
|
+
and reduce I/O overhead when storing large numbers of validation results.
|
|
5
|
+
|
|
6
|
+
Features:
|
|
7
|
+
- Configurable batch sizes and flush intervals
|
|
8
|
+
- Memory-aware buffer management
|
|
9
|
+
- Parallel batch processing
|
|
10
|
+
- Compression support for batched writes
|
|
11
|
+
- Automatic retry with exponential backoff
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
>>> from truthound.stores.batching import (
|
|
15
|
+
... BatchedStore,
|
|
16
|
+
... BatchConfig,
|
|
17
|
+
... BatchWriter,
|
|
18
|
+
... )
|
|
19
|
+
>>>
|
|
20
|
+
>>> config = BatchConfig(
|
|
21
|
+
... batch_size=1000,
|
|
22
|
+
... flush_interval_seconds=5.0,
|
|
23
|
+
... max_buffer_memory_mb=100,
|
|
24
|
+
... )
|
|
25
|
+
>>> store = BatchedStore(underlying_store, config)
|
|
26
|
+
>>>
|
|
27
|
+
>>> async with store:
|
|
28
|
+
... for result in results:
|
|
29
|
+
... await store.add(result)
|
|
30
|
+
... await store.flush()
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
from truthound.stores.batching.base import (
|
|
34
|
+
BatchConfig,
|
|
35
|
+
BatchMetrics,
|
|
36
|
+
BatchState,
|
|
37
|
+
BatchStatus,
|
|
38
|
+
)
|
|
39
|
+
from truthound.stores.batching.writer import (
|
|
40
|
+
BatchWriter,
|
|
41
|
+
AsyncBatchWriter,
|
|
42
|
+
)
|
|
43
|
+
from truthound.stores.batching.store import (
|
|
44
|
+
BatchedStore,
|
|
45
|
+
)
|
|
46
|
+
from truthound.stores.batching.buffer import (
|
|
47
|
+
BatchBuffer,
|
|
48
|
+
MemoryAwareBuffer,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
__all__ = [
|
|
52
|
+
# Base
|
|
53
|
+
"BatchConfig",
|
|
54
|
+
"BatchMetrics",
|
|
55
|
+
"BatchState",
|
|
56
|
+
"BatchStatus",
|
|
57
|
+
# Writer
|
|
58
|
+
"BatchWriter",
|
|
59
|
+
"AsyncBatchWriter",
|
|
60
|
+
# Store
|
|
61
|
+
"BatchedStore",
|
|
62
|
+
# Buffer
|
|
63
|
+
"BatchBuffer",
|
|
64
|
+
"MemoryAwareBuffer",
|
|
65
|
+
]
|