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,469 @@
|
|
|
1
|
+
"""Component registry for the report generation pipeline.
|
|
2
|
+
|
|
3
|
+
This module provides a centralized registry for all pipeline components:
|
|
4
|
+
- Transformers
|
|
5
|
+
- Renderers
|
|
6
|
+
- Themes
|
|
7
|
+
- Exporters
|
|
8
|
+
|
|
9
|
+
The registry supports both programmatic registration and decorator-based registration.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from typing import Any, Callable, TypeVar, TYPE_CHECKING
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from truthound.datadocs.transformers.base import Transformer
|
|
18
|
+
from truthound.datadocs.renderers.base import Renderer
|
|
19
|
+
from truthound.datadocs.themes.base import Theme
|
|
20
|
+
from truthound.datadocs.exporters.base import Exporter
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
T = TypeVar("T")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ComponentRegistry:
|
|
27
|
+
"""Centralized registry for pipeline components.
|
|
28
|
+
|
|
29
|
+
This registry maintains collections of:
|
|
30
|
+
- Transformers: Data transformation stages
|
|
31
|
+
- Renderers: Template rendering engines
|
|
32
|
+
- Themes: Visual styling configurations
|
|
33
|
+
- Exporters: Output format handlers
|
|
34
|
+
|
|
35
|
+
Components can be registered by name and retrieved for use in the pipeline.
|
|
36
|
+
|
|
37
|
+
Example:
|
|
38
|
+
registry = ComponentRegistry()
|
|
39
|
+
|
|
40
|
+
# Register components
|
|
41
|
+
registry.register_transformer("i18n", I18nTransformer)
|
|
42
|
+
registry.register_theme("enterprise", EnterpriseTheme)
|
|
43
|
+
|
|
44
|
+
# Retrieve components
|
|
45
|
+
transformer = registry.get_transformer("i18n")
|
|
46
|
+
theme = registry.get_theme("enterprise")
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def __init__(self) -> None:
|
|
50
|
+
"""Initialize an empty registry."""
|
|
51
|
+
self._transformers: dict[str, type] = {}
|
|
52
|
+
self._renderers: dict[str, type] = {}
|
|
53
|
+
self._themes: dict[str, type | Any] = {}
|
|
54
|
+
self._exporters: dict[str, type] = {}
|
|
55
|
+
self._theme_instances: dict[str, Any] = {}
|
|
56
|
+
|
|
57
|
+
# Transformer registration
|
|
58
|
+
|
|
59
|
+
def register_transformer(
|
|
60
|
+
self,
|
|
61
|
+
name: str,
|
|
62
|
+
transformer_class: type,
|
|
63
|
+
replace: bool = False,
|
|
64
|
+
) -> None:
|
|
65
|
+
"""Register a transformer class.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
name: Unique name for the transformer.
|
|
69
|
+
transformer_class: Transformer class to register.
|
|
70
|
+
replace: If True, replace existing registration.
|
|
71
|
+
|
|
72
|
+
Raises:
|
|
73
|
+
ValueError: If name already exists and replace is False.
|
|
74
|
+
"""
|
|
75
|
+
if name in self._transformers and not replace:
|
|
76
|
+
raise ValueError(f"Transformer '{name}' already registered")
|
|
77
|
+
self._transformers[name] = transformer_class
|
|
78
|
+
|
|
79
|
+
def get_transformer(
|
|
80
|
+
self,
|
|
81
|
+
name: str,
|
|
82
|
+
**kwargs: Any,
|
|
83
|
+
) -> "Transformer":
|
|
84
|
+
"""Get a transformer instance by name.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
name: Transformer name.
|
|
88
|
+
**kwargs: Arguments to pass to the constructor.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
Transformer instance.
|
|
92
|
+
|
|
93
|
+
Raises:
|
|
94
|
+
KeyError: If transformer not found.
|
|
95
|
+
"""
|
|
96
|
+
if name not in self._transformers:
|
|
97
|
+
available = list(self._transformers.keys())
|
|
98
|
+
raise KeyError(
|
|
99
|
+
f"Transformer '{name}' not found. Available: {available}"
|
|
100
|
+
)
|
|
101
|
+
return self._transformers[name](**kwargs)
|
|
102
|
+
|
|
103
|
+
def list_transformers(self) -> list[str]:
|
|
104
|
+
"""List all registered transformer names.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
List of transformer names.
|
|
108
|
+
"""
|
|
109
|
+
return list(self._transformers.keys())
|
|
110
|
+
|
|
111
|
+
def has_transformer(self, name: str) -> bool:
|
|
112
|
+
"""Check if a transformer is registered.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
name: Transformer name.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
True if registered.
|
|
119
|
+
"""
|
|
120
|
+
return name in self._transformers
|
|
121
|
+
|
|
122
|
+
# Renderer registration
|
|
123
|
+
|
|
124
|
+
def register_renderer(
|
|
125
|
+
self,
|
|
126
|
+
name: str,
|
|
127
|
+
renderer_class: type,
|
|
128
|
+
replace: bool = False,
|
|
129
|
+
) -> None:
|
|
130
|
+
"""Register a renderer class.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
name: Unique name for the renderer.
|
|
134
|
+
renderer_class: Renderer class to register.
|
|
135
|
+
replace: If True, replace existing registration.
|
|
136
|
+
|
|
137
|
+
Raises:
|
|
138
|
+
ValueError: If name already exists and replace is False.
|
|
139
|
+
"""
|
|
140
|
+
if name in self._renderers and not replace:
|
|
141
|
+
raise ValueError(f"Renderer '{name}' already registered")
|
|
142
|
+
self._renderers[name] = renderer_class
|
|
143
|
+
|
|
144
|
+
def get_renderer(
|
|
145
|
+
self,
|
|
146
|
+
name: str,
|
|
147
|
+
**kwargs: Any,
|
|
148
|
+
) -> "Renderer":
|
|
149
|
+
"""Get a renderer instance by name.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
name: Renderer name.
|
|
153
|
+
**kwargs: Arguments to pass to the constructor.
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
Renderer instance.
|
|
157
|
+
|
|
158
|
+
Raises:
|
|
159
|
+
KeyError: If renderer not found.
|
|
160
|
+
"""
|
|
161
|
+
if name not in self._renderers:
|
|
162
|
+
available = list(self._renderers.keys())
|
|
163
|
+
raise KeyError(
|
|
164
|
+
f"Renderer '{name}' not found. Available: {available}"
|
|
165
|
+
)
|
|
166
|
+
return self._renderers[name](**kwargs)
|
|
167
|
+
|
|
168
|
+
def list_renderers(self) -> list[str]:
|
|
169
|
+
"""List all registered renderer names.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
List of renderer names.
|
|
173
|
+
"""
|
|
174
|
+
return list(self._renderers.keys())
|
|
175
|
+
|
|
176
|
+
def has_renderer(self, name: str) -> bool:
|
|
177
|
+
"""Check if a renderer is registered.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
name: Renderer name.
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
True if registered.
|
|
184
|
+
"""
|
|
185
|
+
return name in self._renderers
|
|
186
|
+
|
|
187
|
+
# Theme registration
|
|
188
|
+
|
|
189
|
+
def register_theme(
|
|
190
|
+
self,
|
|
191
|
+
name: str,
|
|
192
|
+
theme: type | Any,
|
|
193
|
+
replace: bool = False,
|
|
194
|
+
) -> None:
|
|
195
|
+
"""Register a theme class or instance.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
name: Unique name for the theme.
|
|
199
|
+
theme: Theme class or instance to register.
|
|
200
|
+
replace: If True, replace existing registration.
|
|
201
|
+
|
|
202
|
+
Raises:
|
|
203
|
+
ValueError: If name already exists and replace is False.
|
|
204
|
+
"""
|
|
205
|
+
if name in self._themes and not replace:
|
|
206
|
+
raise ValueError(f"Theme '{name}' already registered")
|
|
207
|
+
self._themes[name] = theme
|
|
208
|
+
|
|
209
|
+
# If it's an instance, cache it
|
|
210
|
+
if not isinstance(theme, type):
|
|
211
|
+
self._theme_instances[name] = theme
|
|
212
|
+
|
|
213
|
+
def get_theme(
|
|
214
|
+
self,
|
|
215
|
+
name: str,
|
|
216
|
+
**kwargs: Any,
|
|
217
|
+
) -> "Theme":
|
|
218
|
+
"""Get a theme instance by name.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
name: Theme name.
|
|
222
|
+
**kwargs: Arguments to pass to the constructor (if class).
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
Theme instance.
|
|
226
|
+
|
|
227
|
+
Raises:
|
|
228
|
+
KeyError: If theme not found.
|
|
229
|
+
"""
|
|
230
|
+
if name not in self._themes:
|
|
231
|
+
available = list(self._themes.keys())
|
|
232
|
+
raise KeyError(
|
|
233
|
+
f"Theme '{name}' not found. Available: {available}"
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
# Return cached instance if available
|
|
237
|
+
if name in self._theme_instances and not kwargs:
|
|
238
|
+
return self._theme_instances[name]
|
|
239
|
+
|
|
240
|
+
theme = self._themes[name]
|
|
241
|
+
if isinstance(theme, type):
|
|
242
|
+
instance = theme(**kwargs)
|
|
243
|
+
# Cache if no kwargs
|
|
244
|
+
if not kwargs:
|
|
245
|
+
self._theme_instances[name] = instance
|
|
246
|
+
return instance
|
|
247
|
+
return theme
|
|
248
|
+
|
|
249
|
+
def list_themes(self) -> list[str]:
|
|
250
|
+
"""List all registered theme names.
|
|
251
|
+
|
|
252
|
+
Returns:
|
|
253
|
+
List of theme names.
|
|
254
|
+
"""
|
|
255
|
+
return list(self._themes.keys())
|
|
256
|
+
|
|
257
|
+
def has_theme(self, name: str) -> bool:
|
|
258
|
+
"""Check if a theme is registered.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
name: Theme name.
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
True if registered.
|
|
265
|
+
"""
|
|
266
|
+
return name in self._themes
|
|
267
|
+
|
|
268
|
+
# Exporter registration
|
|
269
|
+
|
|
270
|
+
def register_exporter(
|
|
271
|
+
self,
|
|
272
|
+
name: str,
|
|
273
|
+
exporter_class: type,
|
|
274
|
+
replace: bool = False,
|
|
275
|
+
) -> None:
|
|
276
|
+
"""Register an exporter class.
|
|
277
|
+
|
|
278
|
+
Args:
|
|
279
|
+
name: Unique name for the exporter (usually format like 'html', 'pdf').
|
|
280
|
+
exporter_class: Exporter class to register.
|
|
281
|
+
replace: If True, replace existing registration.
|
|
282
|
+
|
|
283
|
+
Raises:
|
|
284
|
+
ValueError: If name already exists and replace is False.
|
|
285
|
+
"""
|
|
286
|
+
if name in self._exporters and not replace:
|
|
287
|
+
raise ValueError(f"Exporter '{name}' already registered")
|
|
288
|
+
self._exporters[name] = exporter_class
|
|
289
|
+
|
|
290
|
+
def get_exporter(
|
|
291
|
+
self,
|
|
292
|
+
name: str,
|
|
293
|
+
**kwargs: Any,
|
|
294
|
+
) -> "Exporter":
|
|
295
|
+
"""Get an exporter instance by name.
|
|
296
|
+
|
|
297
|
+
Args:
|
|
298
|
+
name: Exporter name (format).
|
|
299
|
+
**kwargs: Arguments to pass to the constructor.
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
Exporter instance.
|
|
303
|
+
|
|
304
|
+
Raises:
|
|
305
|
+
KeyError: If exporter not found.
|
|
306
|
+
"""
|
|
307
|
+
if name not in self._exporters:
|
|
308
|
+
available = list(self._exporters.keys())
|
|
309
|
+
raise KeyError(
|
|
310
|
+
f"Exporter '{name}' not found. Available: {available}"
|
|
311
|
+
)
|
|
312
|
+
return self._exporters[name](**kwargs)
|
|
313
|
+
|
|
314
|
+
def list_exporters(self) -> list[str]:
|
|
315
|
+
"""List all registered exporter names.
|
|
316
|
+
|
|
317
|
+
Returns:
|
|
318
|
+
List of exporter names (formats).
|
|
319
|
+
"""
|
|
320
|
+
return list(self._exporters.keys())
|
|
321
|
+
|
|
322
|
+
def has_exporter(self, name: str) -> bool:
|
|
323
|
+
"""Check if an exporter is registered.
|
|
324
|
+
|
|
325
|
+
Args:
|
|
326
|
+
name: Exporter name.
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
True if registered.
|
|
330
|
+
"""
|
|
331
|
+
return name in self._exporters
|
|
332
|
+
|
|
333
|
+
# Utility methods
|
|
334
|
+
|
|
335
|
+
def clear(self) -> None:
|
|
336
|
+
"""Clear all registrations."""
|
|
337
|
+
self._transformers.clear()
|
|
338
|
+
self._renderers.clear()
|
|
339
|
+
self._themes.clear()
|
|
340
|
+
self._exporters.clear()
|
|
341
|
+
self._theme_instances.clear()
|
|
342
|
+
|
|
343
|
+
def stats(self) -> dict[str, int]:
|
|
344
|
+
"""Get registration statistics.
|
|
345
|
+
|
|
346
|
+
Returns:
|
|
347
|
+
Dictionary with counts of each component type.
|
|
348
|
+
"""
|
|
349
|
+
return {
|
|
350
|
+
"transformers": len(self._transformers),
|
|
351
|
+
"renderers": len(self._renderers),
|
|
352
|
+
"themes": len(self._themes),
|
|
353
|
+
"exporters": len(self._exporters),
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
# Global registry instance
|
|
358
|
+
component_registry = ComponentRegistry()
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
# Decorator factories for registration
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def register_transformer(
|
|
365
|
+
name: str,
|
|
366
|
+
registry: ComponentRegistry | None = None,
|
|
367
|
+
) -> Callable[[type[T]], type[T]]:
|
|
368
|
+
"""Decorator to register a transformer class.
|
|
369
|
+
|
|
370
|
+
Args:
|
|
371
|
+
name: Unique name for the transformer.
|
|
372
|
+
registry: Registry to use (default: global registry).
|
|
373
|
+
|
|
374
|
+
Returns:
|
|
375
|
+
Decorator function.
|
|
376
|
+
|
|
377
|
+
Example:
|
|
378
|
+
@register_transformer("i18n")
|
|
379
|
+
class I18nTransformer:
|
|
380
|
+
...
|
|
381
|
+
"""
|
|
382
|
+
reg = registry or component_registry
|
|
383
|
+
|
|
384
|
+
def decorator(cls: type[T]) -> type[T]:
|
|
385
|
+
reg.register_transformer(name, cls)
|
|
386
|
+
return cls
|
|
387
|
+
|
|
388
|
+
return decorator
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
def register_renderer(
|
|
392
|
+
name: str,
|
|
393
|
+
registry: ComponentRegistry | None = None,
|
|
394
|
+
) -> Callable[[type[T]], type[T]]:
|
|
395
|
+
"""Decorator to register a renderer class.
|
|
396
|
+
|
|
397
|
+
Args:
|
|
398
|
+
name: Unique name for the renderer.
|
|
399
|
+
registry: Registry to use (default: global registry).
|
|
400
|
+
|
|
401
|
+
Returns:
|
|
402
|
+
Decorator function.
|
|
403
|
+
|
|
404
|
+
Example:
|
|
405
|
+
@register_renderer("jinja")
|
|
406
|
+
class JinjaRenderer:
|
|
407
|
+
...
|
|
408
|
+
"""
|
|
409
|
+
reg = registry or component_registry
|
|
410
|
+
|
|
411
|
+
def decorator(cls: type[T]) -> type[T]:
|
|
412
|
+
reg.register_renderer(name, cls)
|
|
413
|
+
return cls
|
|
414
|
+
|
|
415
|
+
return decorator
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
def register_theme(
|
|
419
|
+
name: str,
|
|
420
|
+
registry: ComponentRegistry | None = None,
|
|
421
|
+
) -> Callable[[type[T]], type[T]]:
|
|
422
|
+
"""Decorator to register a theme class.
|
|
423
|
+
|
|
424
|
+
Args:
|
|
425
|
+
name: Unique name for the theme.
|
|
426
|
+
registry: Registry to use (default: global registry).
|
|
427
|
+
|
|
428
|
+
Returns:
|
|
429
|
+
Decorator function.
|
|
430
|
+
|
|
431
|
+
Example:
|
|
432
|
+
@register_theme("enterprise")
|
|
433
|
+
class EnterpriseTheme:
|
|
434
|
+
...
|
|
435
|
+
"""
|
|
436
|
+
reg = registry or component_registry
|
|
437
|
+
|
|
438
|
+
def decorator(cls: type[T]) -> type[T]:
|
|
439
|
+
reg.register_theme(name, cls)
|
|
440
|
+
return cls
|
|
441
|
+
|
|
442
|
+
return decorator
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
def register_exporter(
|
|
446
|
+
name: str,
|
|
447
|
+
registry: ComponentRegistry | None = None,
|
|
448
|
+
) -> Callable[[type[T]], type[T]]:
|
|
449
|
+
"""Decorator to register an exporter class.
|
|
450
|
+
|
|
451
|
+
Args:
|
|
452
|
+
name: Unique name for the exporter (format).
|
|
453
|
+
registry: Registry to use (default: global registry).
|
|
454
|
+
|
|
455
|
+
Returns:
|
|
456
|
+
Decorator function.
|
|
457
|
+
|
|
458
|
+
Example:
|
|
459
|
+
@register_exporter("pdf")
|
|
460
|
+
class PdfExporter:
|
|
461
|
+
...
|
|
462
|
+
"""
|
|
463
|
+
reg = registry or component_registry
|
|
464
|
+
|
|
465
|
+
def decorator(cls: type[T]) -> type[T]:
|
|
466
|
+
reg.register_exporter(name, cls)
|
|
467
|
+
return cls
|
|
468
|
+
|
|
469
|
+
return decorator
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Exporters for the Data Docs report pipeline.
|
|
2
|
+
|
|
3
|
+
Exporters convert rendered HTML to various output formats.
|
|
4
|
+
|
|
5
|
+
Available Exporters:
|
|
6
|
+
- HtmlExporter: HTML output (default)
|
|
7
|
+
- PdfExporter: PDF output with optimized rendering
|
|
8
|
+
- MarkdownExporter: Markdown output
|
|
9
|
+
- JsonExporter: JSON output (structured data)
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from truthound.datadocs.exporters.base import (
|
|
13
|
+
Exporter,
|
|
14
|
+
BaseExporter,
|
|
15
|
+
ExportResult,
|
|
16
|
+
ExportOptions,
|
|
17
|
+
)
|
|
18
|
+
from truthound.datadocs.exporters.html import (
|
|
19
|
+
HtmlExporter,
|
|
20
|
+
)
|
|
21
|
+
from truthound.datadocs.exporters.pdf import (
|
|
22
|
+
PdfExporter,
|
|
23
|
+
OptimizedPdfExporter,
|
|
24
|
+
PdfOptions,
|
|
25
|
+
)
|
|
26
|
+
from truthound.datadocs.exporters.markdown import (
|
|
27
|
+
MarkdownExporter,
|
|
28
|
+
)
|
|
29
|
+
from truthound.datadocs.exporters.json_exporter import (
|
|
30
|
+
JsonExporter,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
__all__ = [
|
|
34
|
+
# Base
|
|
35
|
+
"Exporter",
|
|
36
|
+
"BaseExporter",
|
|
37
|
+
"ExportResult",
|
|
38
|
+
"ExportOptions",
|
|
39
|
+
# HTML
|
|
40
|
+
"HtmlExporter",
|
|
41
|
+
# PDF
|
|
42
|
+
"PdfExporter",
|
|
43
|
+
"OptimizedPdfExporter",
|
|
44
|
+
"PdfOptions",
|
|
45
|
+
# Markdown
|
|
46
|
+
"MarkdownExporter",
|
|
47
|
+
# JSON
|
|
48
|
+
"JsonExporter",
|
|
49
|
+
]
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"""Base classes and protocols for exporters.
|
|
2
|
+
|
|
3
|
+
This module defines the core abstractions for output format exporters
|
|
4
|
+
in the report generation pipeline.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from abc import ABC, abstractmethod
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from typing import Any, Protocol, runtime_checkable, TYPE_CHECKING
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from truthound.datadocs.engine.context import ReportContext
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class ExportOptions:
|
|
19
|
+
"""Options for export operations.
|
|
20
|
+
|
|
21
|
+
Attributes:
|
|
22
|
+
page_size: Page size for PDF (A4, Letter, etc.).
|
|
23
|
+
orientation: Page orientation (portrait, landscape).
|
|
24
|
+
margin_top: Top margin.
|
|
25
|
+
margin_right: Right margin.
|
|
26
|
+
margin_bottom: Bottom margin.
|
|
27
|
+
margin_left: Left margin.
|
|
28
|
+
compress: Whether to compress output.
|
|
29
|
+
include_metadata: Whether to include metadata.
|
|
30
|
+
minify: Whether to minify output.
|
|
31
|
+
"""
|
|
32
|
+
page_size: str = "A4"
|
|
33
|
+
orientation: str = "portrait"
|
|
34
|
+
margin_top: str = "1cm"
|
|
35
|
+
margin_right: str = "1cm"
|
|
36
|
+
margin_bottom: str = "1cm"
|
|
37
|
+
margin_left: str = "1cm"
|
|
38
|
+
compress: bool = True
|
|
39
|
+
include_metadata: bool = True
|
|
40
|
+
minify: bool = False
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass
|
|
44
|
+
class ExportResult:
|
|
45
|
+
"""Result of an export operation.
|
|
46
|
+
|
|
47
|
+
Attributes:
|
|
48
|
+
content: Exported content (bytes or string).
|
|
49
|
+
format: Output format.
|
|
50
|
+
size_bytes: Size of the output in bytes.
|
|
51
|
+
metadata: Additional metadata about the export.
|
|
52
|
+
success: Whether export was successful.
|
|
53
|
+
error: Error message if export failed.
|
|
54
|
+
"""
|
|
55
|
+
content: bytes | str
|
|
56
|
+
format: str
|
|
57
|
+
size_bytes: int = 0
|
|
58
|
+
metadata: dict[str, Any] = field(default_factory=dict)
|
|
59
|
+
success: bool = True
|
|
60
|
+
error: str | None = None
|
|
61
|
+
|
|
62
|
+
def __post_init__(self) -> None:
|
|
63
|
+
if self.size_bytes == 0 and self.content:
|
|
64
|
+
if isinstance(self.content, bytes):
|
|
65
|
+
self.size_bytes = len(self.content)
|
|
66
|
+
else:
|
|
67
|
+
self.size_bytes = len(self.content.encode("utf-8"))
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@runtime_checkable
|
|
71
|
+
class Exporter(Protocol):
|
|
72
|
+
"""Protocol for output format exporters.
|
|
73
|
+
|
|
74
|
+
Exporters receive rendered HTML and convert it to the target format.
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def format(self) -> str:
|
|
79
|
+
"""Get the output format (e.g., 'html', 'pdf')."""
|
|
80
|
+
...
|
|
81
|
+
|
|
82
|
+
def export(
|
|
83
|
+
self,
|
|
84
|
+
content: str,
|
|
85
|
+
ctx: "ReportContext",
|
|
86
|
+
) -> bytes | str:
|
|
87
|
+
"""Export content to the target format.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
content: Rendered HTML content.
|
|
91
|
+
ctx: Report context for additional options.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
Exported content (bytes for binary formats).
|
|
95
|
+
"""
|
|
96
|
+
...
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class BaseExporter(ABC):
|
|
100
|
+
"""Abstract base class for exporters.
|
|
101
|
+
|
|
102
|
+
Provides common functionality and ensures consistent interface.
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
def __init__(
|
|
106
|
+
self,
|
|
107
|
+
options: ExportOptions | None = None,
|
|
108
|
+
name: str | None = None,
|
|
109
|
+
) -> None:
|
|
110
|
+
"""Initialize the exporter.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
options: Export options.
|
|
114
|
+
name: Optional name for this exporter.
|
|
115
|
+
"""
|
|
116
|
+
self._options = options or ExportOptions()
|
|
117
|
+
self._name = name or self.__class__.__name__
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
@abstractmethod
|
|
121
|
+
def format(self) -> str:
|
|
122
|
+
"""Get the output format."""
|
|
123
|
+
pass
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def name(self) -> str:
|
|
127
|
+
"""Get the exporter name."""
|
|
128
|
+
return self._name
|
|
129
|
+
|
|
130
|
+
@property
|
|
131
|
+
def options(self) -> ExportOptions:
|
|
132
|
+
"""Get export options."""
|
|
133
|
+
return self._options
|
|
134
|
+
|
|
135
|
+
def export(
|
|
136
|
+
self,
|
|
137
|
+
content: str,
|
|
138
|
+
ctx: "ReportContext",
|
|
139
|
+
) -> bytes | str:
|
|
140
|
+
"""Export content to the target format.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
content: Rendered HTML content.
|
|
144
|
+
ctx: Report context.
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
Exported content.
|
|
148
|
+
"""
|
|
149
|
+
try:
|
|
150
|
+
result = self._do_export(content, ctx)
|
|
151
|
+
|
|
152
|
+
if isinstance(result, ExportResult):
|
|
153
|
+
if not result.success:
|
|
154
|
+
raise RuntimeError(result.error or "Export failed")
|
|
155
|
+
return result.content
|
|
156
|
+
|
|
157
|
+
return result
|
|
158
|
+
|
|
159
|
+
except Exception as e:
|
|
160
|
+
# Re-raise with context
|
|
161
|
+
raise RuntimeError(
|
|
162
|
+
f"Export to {self.format} failed: {str(e)}"
|
|
163
|
+
) from e
|
|
164
|
+
|
|
165
|
+
@abstractmethod
|
|
166
|
+
def _do_export(
|
|
167
|
+
self,
|
|
168
|
+
content: str,
|
|
169
|
+
ctx: "ReportContext",
|
|
170
|
+
) -> bytes | str | ExportResult:
|
|
171
|
+
"""Perform the actual export.
|
|
172
|
+
|
|
173
|
+
Subclasses implement this method.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
content: Rendered HTML content.
|
|
177
|
+
ctx: Report context.
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
Exported content or ExportResult.
|
|
181
|
+
"""
|
|
182
|
+
pass
|
|
183
|
+
|
|
184
|
+
def with_options(self, **kwargs: Any) -> "BaseExporter":
|
|
185
|
+
"""Create a new exporter with updated options.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
**kwargs: Option values to update.
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
New exporter instance.
|
|
192
|
+
"""
|
|
193
|
+
from dataclasses import replace
|
|
194
|
+
new_options = replace(self._options, **kwargs)
|
|
195
|
+
return self.__class__(options=new_options, name=self._name)
|
|
196
|
+
|
|
197
|
+
def __repr__(self) -> str:
|
|
198
|
+
return f"{self.__class__.__name__}(format={self.format!r})"
|