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
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
"""Base classes and types for Truthound plugins.
|
|
2
|
+
|
|
3
|
+
This module defines the core abstractions for the plugin system:
|
|
4
|
+
- Plugin: Abstract base class for all plugins
|
|
5
|
+
- PluginConfig: Configuration dataclass
|
|
6
|
+
- PluginInfo: Metadata about a plugin
|
|
7
|
+
- PluginType: Enumeration of plugin categories
|
|
8
|
+
- PluginState: Plugin lifecycle states
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from abc import ABC, abstractmethod
|
|
14
|
+
from dataclasses import dataclass, field
|
|
15
|
+
from enum import Enum
|
|
16
|
+
from typing import TYPE_CHECKING, Any, Callable, TypeVar, Generic
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
import re
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from truthound.plugins.manager import PluginManager
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# =============================================================================
|
|
25
|
+
# Plugin Types and States
|
|
26
|
+
# =============================================================================
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class PluginType(str, Enum):
|
|
30
|
+
"""Categories of plugins supported by Truthound."""
|
|
31
|
+
|
|
32
|
+
VALIDATOR = "validator"
|
|
33
|
+
REPORTER = "reporter"
|
|
34
|
+
DATASOURCE = "datasource"
|
|
35
|
+
PROFILER = "profiler"
|
|
36
|
+
HOOK = "hook"
|
|
37
|
+
TRANSFORMER = "transformer" # Data transformation plugins
|
|
38
|
+
EXPORTER = "exporter" # Export to external systems
|
|
39
|
+
CUSTOM = "custom" # Generic extension
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class PluginState(str, Enum):
|
|
43
|
+
"""Lifecycle states for a plugin."""
|
|
44
|
+
|
|
45
|
+
DISCOVERED = "discovered" # Found but not loaded
|
|
46
|
+
LOADING = "loading" # Currently being loaded
|
|
47
|
+
LOADED = "loaded" # Successfully loaded
|
|
48
|
+
ACTIVE = "active" # Enabled and running
|
|
49
|
+
INACTIVE = "inactive" # Loaded but disabled
|
|
50
|
+
ERROR = "error" # Failed to load/run
|
|
51
|
+
UNLOADING = "unloading" # Currently being unloaded
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# =============================================================================
|
|
55
|
+
# Exceptions
|
|
56
|
+
# =============================================================================
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class PluginError(Exception):
|
|
60
|
+
"""Base exception for plugin-related errors."""
|
|
61
|
+
|
|
62
|
+
def __init__(self, message: str, plugin_name: str | None = None):
|
|
63
|
+
self.plugin_name = plugin_name
|
|
64
|
+
super().__init__(message)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class PluginLoadError(PluginError):
|
|
68
|
+
"""Raised when a plugin fails to load."""
|
|
69
|
+
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class PluginNotFoundError(PluginError):
|
|
74
|
+
"""Raised when a requested plugin is not found."""
|
|
75
|
+
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class PluginDependencyError(PluginError):
|
|
80
|
+
"""Raised when plugin dependencies cannot be satisfied."""
|
|
81
|
+
|
|
82
|
+
def __init__(
|
|
83
|
+
self,
|
|
84
|
+
message: str,
|
|
85
|
+
plugin_name: str | None = None,
|
|
86
|
+
missing_deps: list[str] | None = None,
|
|
87
|
+
):
|
|
88
|
+
self.missing_deps = missing_deps or []
|
|
89
|
+
super().__init__(message, plugin_name)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class PluginCompatibilityError(PluginError):
|
|
93
|
+
"""Raised when a plugin is incompatible with the current version."""
|
|
94
|
+
|
|
95
|
+
def __init__(
|
|
96
|
+
self,
|
|
97
|
+
message: str,
|
|
98
|
+
plugin_name: str | None = None,
|
|
99
|
+
required_version: str | None = None,
|
|
100
|
+
current_version: str | None = None,
|
|
101
|
+
):
|
|
102
|
+
self.required_version = required_version
|
|
103
|
+
self.current_version = current_version
|
|
104
|
+
super().__init__(message, plugin_name)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
# =============================================================================
|
|
108
|
+
# Plugin Configuration
|
|
109
|
+
# =============================================================================
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@dataclass
|
|
113
|
+
class PluginConfig:
|
|
114
|
+
"""Configuration for a plugin.
|
|
115
|
+
|
|
116
|
+
Attributes:
|
|
117
|
+
enabled: Whether the plugin is enabled.
|
|
118
|
+
priority: Load order priority (lower = earlier).
|
|
119
|
+
settings: Plugin-specific settings.
|
|
120
|
+
auto_load: Whether to automatically load on discovery.
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
enabled: bool = True
|
|
124
|
+
priority: int = 100
|
|
125
|
+
settings: dict[str, Any] = field(default_factory=dict)
|
|
126
|
+
auto_load: bool = True
|
|
127
|
+
|
|
128
|
+
def merge(self, other: "PluginConfig") -> "PluginConfig":
|
|
129
|
+
"""Merge with another config, other takes precedence."""
|
|
130
|
+
merged_settings = {**self.settings, **other.settings}
|
|
131
|
+
return PluginConfig(
|
|
132
|
+
enabled=other.enabled,
|
|
133
|
+
priority=other.priority,
|
|
134
|
+
settings=merged_settings,
|
|
135
|
+
auto_load=other.auto_load,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
@dataclass(frozen=True)
|
|
140
|
+
class PluginInfo:
|
|
141
|
+
"""Metadata about a plugin.
|
|
142
|
+
|
|
143
|
+
This is immutable to ensure plugin metadata remains consistent.
|
|
144
|
+
|
|
145
|
+
Attributes:
|
|
146
|
+
name: Unique identifier for the plugin.
|
|
147
|
+
version: Semantic version string.
|
|
148
|
+
plugin_type: Category of plugin.
|
|
149
|
+
description: Human-readable description.
|
|
150
|
+
author: Plugin author.
|
|
151
|
+
homepage: URL to plugin homepage/repository.
|
|
152
|
+
license: License identifier.
|
|
153
|
+
min_truthound_version: Minimum compatible Truthound version.
|
|
154
|
+
max_truthound_version: Maximum compatible Truthound version.
|
|
155
|
+
dependencies: List of required plugin names.
|
|
156
|
+
python_dependencies: List of required Python packages.
|
|
157
|
+
tags: Searchable tags.
|
|
158
|
+
"""
|
|
159
|
+
|
|
160
|
+
name: str
|
|
161
|
+
version: str
|
|
162
|
+
plugin_type: PluginType
|
|
163
|
+
description: str = ""
|
|
164
|
+
author: str = ""
|
|
165
|
+
homepage: str = ""
|
|
166
|
+
license: str = ""
|
|
167
|
+
min_truthound_version: str | None = None
|
|
168
|
+
max_truthound_version: str | None = None
|
|
169
|
+
dependencies: tuple[str, ...] = field(default_factory=tuple)
|
|
170
|
+
python_dependencies: tuple[str, ...] = field(default_factory=tuple)
|
|
171
|
+
tags: tuple[str, ...] = field(default_factory=tuple)
|
|
172
|
+
|
|
173
|
+
def __post_init__(self) -> None:
|
|
174
|
+
"""Validate plugin info after initialization."""
|
|
175
|
+
if not self.name:
|
|
176
|
+
raise ValueError("Plugin name cannot be empty")
|
|
177
|
+
if not re.match(r"^[a-z][a-z0-9_-]*$", self.name):
|
|
178
|
+
raise ValueError(
|
|
179
|
+
f"Invalid plugin name: {self.name}. "
|
|
180
|
+
"Must start with lowercase letter and contain only "
|
|
181
|
+
"lowercase letters, numbers, hyphens, and underscores."
|
|
182
|
+
)
|
|
183
|
+
if not self.version:
|
|
184
|
+
raise ValueError("Plugin version cannot be empty")
|
|
185
|
+
|
|
186
|
+
def is_compatible(self, truthound_version: str) -> bool:
|
|
187
|
+
"""Check if plugin is compatible with given Truthound version."""
|
|
188
|
+
from packaging.version import Version, InvalidVersion
|
|
189
|
+
|
|
190
|
+
try:
|
|
191
|
+
current = Version(truthound_version)
|
|
192
|
+
|
|
193
|
+
if self.min_truthound_version:
|
|
194
|
+
min_ver = Version(self.min_truthound_version)
|
|
195
|
+
if current < min_ver:
|
|
196
|
+
return False
|
|
197
|
+
|
|
198
|
+
if self.max_truthound_version:
|
|
199
|
+
max_ver = Version(self.max_truthound_version)
|
|
200
|
+
if current > max_ver:
|
|
201
|
+
return False
|
|
202
|
+
|
|
203
|
+
return True
|
|
204
|
+
except InvalidVersion:
|
|
205
|
+
# If versions can't be parsed, assume compatible
|
|
206
|
+
return True
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
# =============================================================================
|
|
210
|
+
# Plugin Base Class
|
|
211
|
+
# =============================================================================
|
|
212
|
+
|
|
213
|
+
ConfigT = TypeVar("ConfigT", bound=PluginConfig)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class Plugin(ABC, Generic[ConfigT]):
|
|
217
|
+
"""Abstract base class for all Truthound plugins.
|
|
218
|
+
|
|
219
|
+
Plugins must implement:
|
|
220
|
+
- info property: Return PluginInfo metadata
|
|
221
|
+
- setup(): Initialize the plugin
|
|
222
|
+
- teardown(): Cleanup on unload
|
|
223
|
+
|
|
224
|
+
Plugins may optionally implement:
|
|
225
|
+
- register(): Register components (validators, reporters, etc.)
|
|
226
|
+
- on_config_change(): Handle configuration updates
|
|
227
|
+
- health_check(): Verify plugin is functioning
|
|
228
|
+
|
|
229
|
+
Example:
|
|
230
|
+
>>> class MyValidatorPlugin(Plugin):
|
|
231
|
+
... @property
|
|
232
|
+
... def info(self) -> PluginInfo:
|
|
233
|
+
... return PluginInfo(
|
|
234
|
+
... name="my-validator",
|
|
235
|
+
... version="1.0.0",
|
|
236
|
+
... plugin_type=PluginType.VALIDATOR,
|
|
237
|
+
... description="Custom validation rules",
|
|
238
|
+
... )
|
|
239
|
+
...
|
|
240
|
+
... def setup(self) -> None:
|
|
241
|
+
... # Initialize resources
|
|
242
|
+
... pass
|
|
243
|
+
...
|
|
244
|
+
... def teardown(self) -> None:
|
|
245
|
+
... # Cleanup resources
|
|
246
|
+
... pass
|
|
247
|
+
...
|
|
248
|
+
... def register(self, manager: PluginManager) -> None:
|
|
249
|
+
... # Register validators
|
|
250
|
+
... from truthound.validators.registry import registry
|
|
251
|
+
... registry.register(MyCustomValidator)
|
|
252
|
+
"""
|
|
253
|
+
|
|
254
|
+
def __init__(self, config: ConfigT | None = None):
|
|
255
|
+
"""Initialize the plugin.
|
|
256
|
+
|
|
257
|
+
Args:
|
|
258
|
+
config: Optional plugin configuration.
|
|
259
|
+
"""
|
|
260
|
+
self._config: ConfigT = config or self._default_config() # type: ignore
|
|
261
|
+
self._state: PluginState = PluginState.DISCOVERED
|
|
262
|
+
self._manager: PluginManager | None = None
|
|
263
|
+
self._error: Exception | None = None
|
|
264
|
+
|
|
265
|
+
@property
|
|
266
|
+
@abstractmethod
|
|
267
|
+
def info(self) -> PluginInfo:
|
|
268
|
+
"""Return plugin metadata.
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
PluginInfo with plugin name, version, type, etc.
|
|
272
|
+
"""
|
|
273
|
+
...
|
|
274
|
+
|
|
275
|
+
@abstractmethod
|
|
276
|
+
def setup(self) -> None:
|
|
277
|
+
"""Initialize the plugin.
|
|
278
|
+
|
|
279
|
+
Called when the plugin is loaded. Use this to:
|
|
280
|
+
- Initialize resources
|
|
281
|
+
- Establish connections
|
|
282
|
+
- Load configuration
|
|
283
|
+
"""
|
|
284
|
+
...
|
|
285
|
+
|
|
286
|
+
@abstractmethod
|
|
287
|
+
def teardown(self) -> None:
|
|
288
|
+
"""Cleanup plugin resources.
|
|
289
|
+
|
|
290
|
+
Called when the plugin is unloaded. Use this to:
|
|
291
|
+
- Close connections
|
|
292
|
+
- Release resources
|
|
293
|
+
- Save state
|
|
294
|
+
"""
|
|
295
|
+
...
|
|
296
|
+
|
|
297
|
+
def register(self, manager: "PluginManager") -> None:
|
|
298
|
+
"""Register plugin components.
|
|
299
|
+
|
|
300
|
+
Override this to register validators, reporters, etc.
|
|
301
|
+
Called after setup() completes successfully.
|
|
302
|
+
|
|
303
|
+
Args:
|
|
304
|
+
manager: The plugin manager instance.
|
|
305
|
+
"""
|
|
306
|
+
pass
|
|
307
|
+
|
|
308
|
+
def unregister(self, manager: "PluginManager") -> None:
|
|
309
|
+
"""Unregister plugin components.
|
|
310
|
+
|
|
311
|
+
Override this to unregister validators, reporters, etc.
|
|
312
|
+
Called before teardown().
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
manager: The plugin manager instance.
|
|
316
|
+
"""
|
|
317
|
+
pass
|
|
318
|
+
|
|
319
|
+
def on_config_change(self, old_config: ConfigT, new_config: ConfigT) -> None:
|
|
320
|
+
"""Handle configuration changes.
|
|
321
|
+
|
|
322
|
+
Override to respond to configuration updates at runtime.
|
|
323
|
+
|
|
324
|
+
Args:
|
|
325
|
+
old_config: Previous configuration.
|
|
326
|
+
new_config: New configuration.
|
|
327
|
+
"""
|
|
328
|
+
pass
|
|
329
|
+
|
|
330
|
+
def health_check(self) -> bool:
|
|
331
|
+
"""Verify plugin is functioning correctly.
|
|
332
|
+
|
|
333
|
+
Returns:
|
|
334
|
+
True if healthy, False otherwise.
|
|
335
|
+
"""
|
|
336
|
+
return self._state == PluginState.ACTIVE
|
|
337
|
+
|
|
338
|
+
@property
|
|
339
|
+
def config(self) -> ConfigT:
|
|
340
|
+
"""Get plugin configuration."""
|
|
341
|
+
return self._config
|
|
342
|
+
|
|
343
|
+
@config.setter
|
|
344
|
+
def config(self, value: ConfigT) -> None:
|
|
345
|
+
"""Set plugin configuration with change notification."""
|
|
346
|
+
old_config = self._config
|
|
347
|
+
self._config = value
|
|
348
|
+
if self._state == PluginState.ACTIVE:
|
|
349
|
+
self.on_config_change(old_config, value)
|
|
350
|
+
|
|
351
|
+
@property
|
|
352
|
+
def state(self) -> PluginState:
|
|
353
|
+
"""Get current plugin state."""
|
|
354
|
+
return self._state
|
|
355
|
+
|
|
356
|
+
@property
|
|
357
|
+
def name(self) -> str:
|
|
358
|
+
"""Get plugin name (convenience property)."""
|
|
359
|
+
return self.info.name
|
|
360
|
+
|
|
361
|
+
@property
|
|
362
|
+
def version(self) -> str:
|
|
363
|
+
"""Get plugin version (convenience property)."""
|
|
364
|
+
return self.info.version
|
|
365
|
+
|
|
366
|
+
@property
|
|
367
|
+
def plugin_type(self) -> PluginType:
|
|
368
|
+
"""Get plugin type (convenience property)."""
|
|
369
|
+
return self.info.plugin_type
|
|
370
|
+
|
|
371
|
+
@property
|
|
372
|
+
def error(self) -> Exception | None:
|
|
373
|
+
"""Get error if plugin is in error state."""
|
|
374
|
+
return self._error
|
|
375
|
+
|
|
376
|
+
def _default_config(self) -> PluginConfig:
|
|
377
|
+
"""Return default configuration.
|
|
378
|
+
|
|
379
|
+
Override in subclasses that use custom config types.
|
|
380
|
+
"""
|
|
381
|
+
return PluginConfig()
|
|
382
|
+
|
|
383
|
+
def __repr__(self) -> str:
|
|
384
|
+
return (
|
|
385
|
+
f"<{self.__class__.__name__} "
|
|
386
|
+
f"name={self.name!r} "
|
|
387
|
+
f"version={self.version!r} "
|
|
388
|
+
f"state={self.state.value!r}>"
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
# =============================================================================
|
|
393
|
+
# Specialized Plugin Base Classes
|
|
394
|
+
# =============================================================================
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
class ValidatorPlugin(Plugin[PluginConfig]):
|
|
398
|
+
"""Base class for validator plugins.
|
|
399
|
+
|
|
400
|
+
Provides convenience methods for registering validators.
|
|
401
|
+
"""
|
|
402
|
+
|
|
403
|
+
@property
|
|
404
|
+
def info(self) -> PluginInfo:
|
|
405
|
+
return PluginInfo(
|
|
406
|
+
name=self._get_plugin_name(),
|
|
407
|
+
version=self._get_plugin_version(),
|
|
408
|
+
plugin_type=PluginType.VALIDATOR,
|
|
409
|
+
description=self._get_description(),
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
def _get_plugin_name(self) -> str:
|
|
413
|
+
"""Override to provide plugin name."""
|
|
414
|
+
return self.__class__.__name__.lower().replace("plugin", "")
|
|
415
|
+
|
|
416
|
+
def _get_plugin_version(self) -> str:
|
|
417
|
+
"""Override to provide plugin version."""
|
|
418
|
+
return "1.0.0"
|
|
419
|
+
|
|
420
|
+
def _get_description(self) -> str:
|
|
421
|
+
"""Override to provide description."""
|
|
422
|
+
return self.__class__.__doc__ or ""
|
|
423
|
+
|
|
424
|
+
@abstractmethod
|
|
425
|
+
def get_validators(self) -> list[type]:
|
|
426
|
+
"""Return list of validator classes to register.
|
|
427
|
+
|
|
428
|
+
Returns:
|
|
429
|
+
List of Validator subclasses.
|
|
430
|
+
"""
|
|
431
|
+
...
|
|
432
|
+
|
|
433
|
+
def register(self, manager: "PluginManager") -> None:
|
|
434
|
+
"""Register validators with the validator registry."""
|
|
435
|
+
from truthound.validators.registry import registry
|
|
436
|
+
|
|
437
|
+
for validator_cls in self.get_validators():
|
|
438
|
+
registry.register(validator_cls)
|
|
439
|
+
|
|
440
|
+
def setup(self) -> None:
|
|
441
|
+
"""Default setup - no action needed."""
|
|
442
|
+
pass
|
|
443
|
+
|
|
444
|
+
def teardown(self) -> None:
|
|
445
|
+
"""Default teardown - no action needed."""
|
|
446
|
+
pass
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
class ReporterPlugin(Plugin[PluginConfig]):
|
|
450
|
+
"""Base class for reporter plugins.
|
|
451
|
+
|
|
452
|
+
Provides convenience methods for registering reporters.
|
|
453
|
+
"""
|
|
454
|
+
|
|
455
|
+
@property
|
|
456
|
+
def info(self) -> PluginInfo:
|
|
457
|
+
return PluginInfo(
|
|
458
|
+
name=self._get_plugin_name(),
|
|
459
|
+
version=self._get_plugin_version(),
|
|
460
|
+
plugin_type=PluginType.REPORTER,
|
|
461
|
+
description=self._get_description(),
|
|
462
|
+
)
|
|
463
|
+
|
|
464
|
+
def _get_plugin_name(self) -> str:
|
|
465
|
+
"""Override to provide plugin name."""
|
|
466
|
+
return self.__class__.__name__.lower().replace("plugin", "")
|
|
467
|
+
|
|
468
|
+
def _get_plugin_version(self) -> str:
|
|
469
|
+
"""Override to provide plugin version."""
|
|
470
|
+
return "1.0.0"
|
|
471
|
+
|
|
472
|
+
def _get_description(self) -> str:
|
|
473
|
+
"""Override to provide description."""
|
|
474
|
+
return self.__class__.__doc__ or ""
|
|
475
|
+
|
|
476
|
+
@abstractmethod
|
|
477
|
+
def get_reporters(self) -> dict[str, type]:
|
|
478
|
+
"""Return dict of format name to reporter class.
|
|
479
|
+
|
|
480
|
+
Returns:
|
|
481
|
+
Dict mapping format names to Reporter subclasses.
|
|
482
|
+
"""
|
|
483
|
+
...
|
|
484
|
+
|
|
485
|
+
def register(self, manager: "PluginManager") -> None:
|
|
486
|
+
"""Register reporters with the reporter factory."""
|
|
487
|
+
from truthound.reporters.factory import register_reporter
|
|
488
|
+
|
|
489
|
+
for format_name, reporter_cls in self.get_reporters().items():
|
|
490
|
+
register_reporter(format_name)(reporter_cls)
|
|
491
|
+
|
|
492
|
+
def setup(self) -> None:
|
|
493
|
+
"""Default setup - no action needed."""
|
|
494
|
+
pass
|
|
495
|
+
|
|
496
|
+
def teardown(self) -> None:
|
|
497
|
+
"""Default teardown - no action needed."""
|
|
498
|
+
pass
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
class DataSourcePlugin(Plugin[PluginConfig]):
|
|
502
|
+
"""Base class for data source plugins.
|
|
503
|
+
|
|
504
|
+
Provides convenience methods for registering data sources.
|
|
505
|
+
"""
|
|
506
|
+
|
|
507
|
+
@property
|
|
508
|
+
def info(self) -> PluginInfo:
|
|
509
|
+
return PluginInfo(
|
|
510
|
+
name=self._get_plugin_name(),
|
|
511
|
+
version=self._get_plugin_version(),
|
|
512
|
+
plugin_type=PluginType.DATASOURCE,
|
|
513
|
+
description=self._get_description(),
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
def _get_plugin_name(self) -> str:
|
|
517
|
+
"""Override to provide plugin name."""
|
|
518
|
+
return self.__class__.__name__.lower().replace("plugin", "")
|
|
519
|
+
|
|
520
|
+
def _get_plugin_version(self) -> str:
|
|
521
|
+
"""Override to provide plugin version."""
|
|
522
|
+
return "1.0.0"
|
|
523
|
+
|
|
524
|
+
def _get_description(self) -> str:
|
|
525
|
+
"""Override to provide description."""
|
|
526
|
+
return self.__class__.__doc__ or ""
|
|
527
|
+
|
|
528
|
+
@abstractmethod
|
|
529
|
+
def get_datasource_types(self) -> dict[str, type]:
|
|
530
|
+
"""Return dict of type name to datasource class.
|
|
531
|
+
|
|
532
|
+
Returns:
|
|
533
|
+
Dict mapping type names to DataSource subclasses.
|
|
534
|
+
"""
|
|
535
|
+
...
|
|
536
|
+
|
|
537
|
+
def setup(self) -> None:
|
|
538
|
+
"""Default setup - no action needed."""
|
|
539
|
+
pass
|
|
540
|
+
|
|
541
|
+
def teardown(self) -> None:
|
|
542
|
+
"""Default teardown - no action needed."""
|
|
543
|
+
pass
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
class HookPlugin(Plugin[PluginConfig]):
|
|
547
|
+
"""Base class for hook plugins.
|
|
548
|
+
|
|
549
|
+
Hook plugins provide event handlers that are called at specific
|
|
550
|
+
points in the validation/profiling lifecycle.
|
|
551
|
+
"""
|
|
552
|
+
|
|
553
|
+
@property
|
|
554
|
+
def info(self) -> PluginInfo:
|
|
555
|
+
return PluginInfo(
|
|
556
|
+
name=self._get_plugin_name(),
|
|
557
|
+
version=self._get_plugin_version(),
|
|
558
|
+
plugin_type=PluginType.HOOK,
|
|
559
|
+
description=self._get_description(),
|
|
560
|
+
)
|
|
561
|
+
|
|
562
|
+
def _get_plugin_name(self) -> str:
|
|
563
|
+
"""Override to provide plugin name."""
|
|
564
|
+
return self.__class__.__name__.lower().replace("plugin", "")
|
|
565
|
+
|
|
566
|
+
def _get_plugin_version(self) -> str:
|
|
567
|
+
"""Override to provide plugin version."""
|
|
568
|
+
return "1.0.0"
|
|
569
|
+
|
|
570
|
+
def _get_description(self) -> str:
|
|
571
|
+
"""Override to provide description."""
|
|
572
|
+
return self.__class__.__doc__ or ""
|
|
573
|
+
|
|
574
|
+
@abstractmethod
|
|
575
|
+
def get_hooks(self) -> dict[str, Callable]:
|
|
576
|
+
"""Return dict of hook name to handler function.
|
|
577
|
+
|
|
578
|
+
Returns:
|
|
579
|
+
Dict mapping hook names to handler functions.
|
|
580
|
+
"""
|
|
581
|
+
...
|
|
582
|
+
|
|
583
|
+
def register(self, manager: "PluginManager") -> None:
|
|
584
|
+
"""Register hooks with the hook manager."""
|
|
585
|
+
for hook_name, handler in self.get_hooks().items():
|
|
586
|
+
manager.hooks.register(hook_name, handler, source=self.name)
|
|
587
|
+
|
|
588
|
+
def unregister(self, manager: "PluginManager") -> None:
|
|
589
|
+
"""Unregister hooks."""
|
|
590
|
+
for hook_name in self.get_hooks().keys():
|
|
591
|
+
manager.hooks.unregister(hook_name, source=self.name)
|
|
592
|
+
|
|
593
|
+
def setup(self) -> None:
|
|
594
|
+
"""Default setup - no action needed."""
|
|
595
|
+
pass
|
|
596
|
+
|
|
597
|
+
def teardown(self) -> None:
|
|
598
|
+
"""Default teardown - no action needed."""
|
|
599
|
+
pass
|