pycharter 0.0.23__tar.gz → 0.0.24__tar.gz
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.
- {pycharter-0.0.23/pycharter.egg-info → pycharter-0.0.24}/PKG-INFO +141 -26
- {pycharter-0.0.23 → pycharter-0.0.24}/README.md +140 -25
- {pycharter-0.0.23 → pycharter-0.0.24}/api/main.py +27 -1
- pycharter-0.0.24/api/models/docs.py +68 -0
- pycharter-0.0.24/api/models/evolution.py +117 -0
- pycharter-0.0.24/api/models/tracking.py +111 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/models/validation.py +46 -6
- {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/__init__.py +14 -1
- pycharter-0.0.24/api/routes/v1/docs.py +187 -0
- pycharter-0.0.24/api/routes/v1/evolution.py +337 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/templates.py +168 -3
- pycharter-0.0.24/api/routes/v1/tracking.py +301 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/validation.py +68 -31
- pycharter-0.0.24/pycharter/__init__.py +421 -0
- pycharter-0.0.24/pycharter/data/templates/contract/template_coercion_rules.yaml +57 -0
- pycharter-0.0.24/pycharter/data/templates/contract/template_contract.yaml +122 -0
- pycharter-0.0.24/pycharter/data/templates/contract/template_metadata.yaml +68 -0
- pycharter-0.0.24/pycharter/data/templates/contract/template_schema.yaml +100 -0
- pycharter-0.0.24/pycharter/data/templates/contract/template_validation_rules.yaml +75 -0
- pycharter-0.0.24/pycharter/data/templates/etl/README.md +224 -0
- pycharter-0.0.24/pycharter/data/templates/etl/extract_cloud_azure.yaml +24 -0
- pycharter-0.0.24/pycharter/data/templates/etl/extract_cloud_gcs.yaml +25 -0
- pycharter-0.0.24/pycharter/data/templates/etl/extract_cloud_s3.yaml +30 -0
- pycharter-0.0.24/pycharter/data/templates/etl/extract_database.yaml +34 -0
- pycharter-0.0.24/pycharter/data/templates/etl/extract_database_ssh.yaml +40 -0
- pycharter-0.0.24/pycharter/data/templates/etl/extract_file_csv.yaml +21 -0
- pycharter-0.0.24/pycharter/data/templates/etl/extract_file_glob.yaml +25 -0
- pycharter-0.0.24/pycharter/data/templates/etl/extract_file_json.yaml +24 -0
- pycharter-0.0.24/pycharter/data/templates/etl/extract_file_parquet.yaml +20 -0
- pycharter-0.0.24/pycharter/data/templates/etl/extract_http_paginated.yaml +79 -0
- pycharter-0.0.24/pycharter/data/templates/etl/extract_http_path_params.yaml +38 -0
- pycharter-0.0.24/pycharter/data/templates/etl/extract_http_simple.yaml +62 -0
- pycharter-0.0.24/pycharter/data/templates/etl/load_cloud_azure.yaml +24 -0
- pycharter-0.0.24/pycharter/data/templates/etl/load_cloud_gcs.yaml +22 -0
- pycharter-0.0.24/pycharter/data/templates/etl/load_cloud_s3.yaml +27 -0
- pycharter-0.0.24/pycharter/data/templates/etl/load_file.yaml +34 -0
- pycharter-0.0.24/pycharter/data/templates/etl/load_insert.yaml +18 -0
- pycharter-0.0.24/pycharter/data/templates/etl/load_postgresql.yaml +39 -0
- pycharter-0.0.24/pycharter/data/templates/etl/load_sqlite.yaml +21 -0
- pycharter-0.0.24/pycharter/data/templates/etl/load_truncate_and_load.yaml +20 -0
- pycharter-0.0.24/pycharter/data/templates/etl/load_upsert.yaml +25 -0
- pycharter-0.0.24/pycharter/data/templates/etl/load_with_dlq.yaml +34 -0
- pycharter-0.0.24/pycharter/data/templates/etl/load_with_ssh_tunnel.yaml +35 -0
- pycharter-0.0.24/pycharter/data/templates/etl/pipeline_http_to_db.yaml +75 -0
- pycharter-0.0.24/pycharter/data/templates/etl/transform_combined.yaml +48 -0
- pycharter-0.0.24/pycharter/data/templates/etl/transform_custom_function.yaml +58 -0
- pycharter-0.0.24/pycharter/data/templates/etl/transform_jsonata.yaml +51 -0
- pycharter-0.0.24/pycharter/data/templates/etl/transform_simple.yaml +59 -0
- pycharter-0.0.24/pycharter/docs_generator/__init__.py +43 -0
- pycharter-0.0.24/pycharter/docs_generator/generator.py +465 -0
- pycharter-0.0.24/pycharter/docs_generator/renderers.py +247 -0
- pycharter-0.0.24/pycharter/etl_generator/__init__.py +182 -0
- pycharter-0.0.24/pycharter/etl_generator/builder.py +121 -0
- pycharter-0.0.24/pycharter/etl_generator/config_loader.py +394 -0
- pycharter-0.0.24/pycharter/etl_generator/config_validator.py +418 -0
- pycharter-0.0.24/pycharter/etl_generator/context.py +132 -0
- pycharter-0.0.24/pycharter/etl_generator/expression.py +499 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/extractors/__init__.py +4 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/extractors/cloud_storage.py +77 -1
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/extractors/database.py +71 -1
- pycharter-0.0.24/pycharter/etl_generator/extractors/factory.py +185 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/extractors/file.py +58 -1
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/extractors/http.py +80 -1
- pycharter-0.0.24/pycharter/etl_generator/extractors/streaming.py +57 -0
- pycharter-0.0.24/pycharter/etl_generator/loaders/__init__.py +41 -0
- pycharter-0.0.24/pycharter/etl_generator/loaders/base.py +35 -0
- pycharter-0.0.24/pycharter/etl_generator/loaders/cloud.py +87 -0
- pycharter-0.0.24/pycharter/etl_generator/loaders/cloud_storage_loader.py +275 -0
- pycharter-0.0.24/pycharter/etl_generator/loaders/database.py +274 -0
- pycharter-0.0.24/pycharter/etl_generator/loaders/factory.py +180 -0
- pycharter-0.0.24/pycharter/etl_generator/loaders/file.py +72 -0
- pycharter-0.0.24/pycharter/etl_generator/loaders/file_loader.py +130 -0
- pycharter-0.0.24/pycharter/etl_generator/pipeline.py +743 -0
- pycharter-0.0.24/pycharter/etl_generator/protocols.py +54 -0
- pycharter-0.0.24/pycharter/etl_generator/result.py +63 -0
- pycharter-0.0.24/pycharter/etl_generator/schemas/__init__.py +49 -0
- pycharter-0.0.24/pycharter/etl_generator/transformers/__init__.py +49 -0
- pycharter-0.0.24/pycharter/etl_generator/transformers/base.py +63 -0
- pycharter-0.0.24/pycharter/etl_generator/transformers/config.py +45 -0
- pycharter-0.0.24/pycharter/etl_generator/transformers/custom_function.py +101 -0
- pycharter-0.0.24/pycharter/etl_generator/transformers/jsonata_transformer.py +56 -0
- pycharter-0.0.24/pycharter/etl_generator/transformers/operations.py +218 -0
- pycharter-0.0.24/pycharter/etl_generator/transformers/pipeline.py +54 -0
- pycharter-0.0.24/pycharter/etl_generator/transformers/simple_operations.py +131 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/quality/__init__.py +25 -0
- pycharter-0.0.24/pycharter/quality/tracking/__init__.py +64 -0
- pycharter-0.0.24/pycharter/quality/tracking/collector.py +318 -0
- pycharter-0.0.24/pycharter/quality/tracking/exporters.py +238 -0
- pycharter-0.0.24/pycharter/quality/tracking/models.py +194 -0
- pycharter-0.0.24/pycharter/quality/tracking/store.py +385 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/runtime_validator/__init__.py +20 -7
- pycharter-0.0.24/pycharter/runtime_validator/builder.py +328 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/runtime_validator/validator.py +311 -7
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/runtime_validator/validator_core.py +61 -0
- pycharter-0.0.24/pycharter/schema_evolution/__init__.py +61 -0
- pycharter-0.0.24/pycharter/schema_evolution/compatibility.py +270 -0
- pycharter-0.0.24/pycharter/schema_evolution/diff.py +496 -0
- pycharter-0.0.24/pycharter/schema_evolution/models.py +201 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/__init__.py +56 -0
- pycharter-0.0.24/pycharter/shared/errors.py +296 -0
- pycharter-0.0.24/pycharter/shared/protocols.py +234 -0
- {pycharter-0.0.23 → pycharter-0.0.24/pycharter.egg-info}/PKG-INFO +141 -26
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter.egg-info/SOURCES.txt +51 -6
- {pycharter-0.0.23 → pycharter-0.0.24}/pyproject.toml +1 -1
- pycharter-0.0.23/pycharter/__init__.py +0 -211
- pycharter-0.0.23/pycharter/data/templates/contract/template_coercion_rules.yaml +0 -15
- pycharter-0.0.23/pycharter/data/templates/contract/template_contract.yaml +0 -587
- pycharter-0.0.23/pycharter/data/templates/contract/template_metadata.yaml +0 -38
- pycharter-0.0.23/pycharter/data/templates/contract/template_schema.yaml +0 -22
- pycharter-0.0.23/pycharter/data/templates/contract/template_validation_rules.yaml +0 -29
- pycharter-0.0.23/pycharter/data/templates/etl/README.md +0 -91
- pycharter-0.0.23/pycharter/data/templates/etl/extract_cloud_azure.yaml +0 -23
- pycharter-0.0.23/pycharter/data/templates/etl/extract_cloud_gcs.yaml +0 -22
- pycharter-0.0.23/pycharter/data/templates/etl/extract_cloud_s3.yaml +0 -24
- pycharter-0.0.23/pycharter/data/templates/etl/extract_database.yaml +0 -28
- pycharter-0.0.23/pycharter/data/templates/etl/extract_database_ssh.yaml +0 -27
- pycharter-0.0.23/pycharter/data/templates/etl/extract_file_csv.yaml +0 -17
- pycharter-0.0.23/pycharter/data/templates/etl/extract_file_glob.yaml +0 -17
- pycharter-0.0.23/pycharter/data/templates/etl/extract_file_json.yaml +0 -14
- pycharter-0.0.23/pycharter/data/templates/etl/extract_file_parquet.yaml +0 -13
- pycharter-0.0.23/pycharter/data/templates/etl/extract_http_paginated.yaml +0 -75
- pycharter-0.0.23/pycharter/data/templates/etl/extract_http_path_params.yaml +0 -45
- pycharter-0.0.23/pycharter/data/templates/etl/extract_http_simple.yaml +0 -52
- pycharter-0.0.23/pycharter/data/templates/etl/load_insert.yaml +0 -17
- pycharter-0.0.23/pycharter/data/templates/etl/load_postgresql.yaml +0 -17
- pycharter-0.0.23/pycharter/data/templates/etl/load_sqlite.yaml +0 -16
- pycharter-0.0.23/pycharter/data/templates/etl/load_truncate_and_load.yaml +0 -18
- pycharter-0.0.23/pycharter/data/templates/etl/load_upsert.yaml +0 -28
- pycharter-0.0.23/pycharter/data/templates/etl/load_with_dlq.yaml +0 -24
- pycharter-0.0.23/pycharter/data/templates/etl/load_with_ssh_tunnel.yaml +0 -28
- pycharter-0.0.23/pycharter/data/templates/etl/pipeline_http_to_db.yaml +0 -38
- pycharter-0.0.23/pycharter/data/templates/etl/transform_combined.yaml +0 -38
- pycharter-0.0.23/pycharter/data/templates/etl/transform_custom_function.yaml +0 -18
- pycharter-0.0.23/pycharter/data/templates/etl/transform_jsonata.yaml +0 -20
- pycharter-0.0.23/pycharter/data/templates/etl/transform_simple.yaml +0 -41
- pycharter-0.0.23/pycharter/etl_generator/__init__.py +0 -94
- pycharter-0.0.23/pycharter/etl_generator/extraction.py +0 -701
- pycharter-0.0.23/pycharter/etl_generator/extractors/factory.py +0 -141
- pycharter-0.0.23/pycharter/etl_generator/factory.py +0 -174
- pycharter-0.0.23/pycharter/etl_generator/orchestrator.py +0 -1650
- pycharter-0.0.23/pycharter/integrations/__init__.py +0 -19
- pycharter-0.0.23/pycharter/integrations/kafka.py +0 -178
- pycharter-0.0.23/pycharter/integrations/streaming.py +0 -100
- {pycharter-0.0.23 → pycharter-0.0.24}/LICENSE +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/MANIFEST.in +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/dependencies/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/dependencies/database.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/dependencies/store.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/models/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/models/contracts.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/models/metadata.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/models/metadata_entities.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/models/quality.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/models/schemas.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/contracts.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/metadata.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/quality.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/schemas.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/settings.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/validation_jobs.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/api/utils.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/cli.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/config.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/contract_builder/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/contract_builder/builder.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/contract_parser/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/contract_parser/parser.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/data/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/cli.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/README +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/env.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/script.py.mako +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20250115120000_add_tier2_tier3_entities.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20251209163657_799b73fe9f6c_initial_schema.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20251209164144_ae0efda02aa1_initial_schema.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20251217160146_f9995dc0f4b3_add_quality_tables.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20251217164915_8b08d78068e3_add_data_version_tracking.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20260110083000_a1b2c3d4e5f6_add_dead_letter_queue_table.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20260120000000_add_name_title_validation_constraints.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20260121000000_remove_artifact_versions_from_data_contracts.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20260122000000_change_artifact_unique_constraints_to_title_version.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/api_endpoint.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/base.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/coercion_rule.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/compliance_framework.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/data_contract.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/data_dependency.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/data_feed.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/dlq.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/domain.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/environment.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/metadata_record.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/owner.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/quality_metric.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/quality_violation.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/schema.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/storage_location.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/system.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/tag.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/validation_rule.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/schemas/.ipynb_checkpoints/data_contract-checkpoint.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/schemas/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/schemas/data_contract.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/checkpoint.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/config_generator.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/database.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/dlq.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/extractors/base.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/progress.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/json_schema_converter/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/json_schema_converter/converter.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/json_schema_converter/reverse_converter.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/metadata_store/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/metadata_store/client.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/metadata_store/in_memory.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/metadata_store/mongodb.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/metadata_store/postgres.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/metadata_store/redis.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/metadata_store/sqlite.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/py.typed +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/pydantic_generator/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/pydantic_generator/converter.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/pydantic_generator/generator.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/quality/check.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/quality/cli.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/quality/metrics.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/quality/models.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/quality/profiling.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/quality/violations.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/runtime_validator/decorators.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/runtime_validator/utils.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/runtime_validator/wrappers.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/coercions/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/coercions/builtin.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/json_schema_support.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/json_schema_validator.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/name_validator.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/schema_parser.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/schema_resolver.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/validations/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/validations/builtin.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/utils/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/utils/value_injector.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/utils/version.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter.egg-info/dependency_links.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter.egg-info/entry_points.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter.egg-info/requires.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/pycharter.egg-info/top_level.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/setup.cfg +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/setup.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_contract_builder.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_contract_parser.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_extractors.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_integration.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_json_schema_compliance.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_json_schema_converter.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_metadata_stores.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_pydantic_generator.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_refs_and_definitions.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_runtime_validator.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_schema_parser.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_value_injector.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_x_validators.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/build.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/dev.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/server.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/.gitkeep +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/404/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/404.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/__next.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/2gKjNv6YvE6BcIdFthBLs/_buildManifest.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/2gKjNv6YvE6BcIdFthBLs/_ssgManifest.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/13d4a0fbd74c1ee4.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/222442f6da32302a.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/247eb132b7f7b574.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/26dfc590f7714c03.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/297d55555b71baba.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/2ab439ce003cd691.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/2edb43b48432ac04.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/34d289e6db2ef551.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/414e77373f8ff61c.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/49ca65abd26ae49e.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/652ad0aa26265c47.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/9667e7a3d359eb39.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/99508d9d5869cc27.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/9c23f44fff36548a.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/a6dad97d9634a72d.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/b313c35a6ba76574.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/b32a0963684b9933.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/c69f6cba366bd988.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/d2363397e1b2bcab.css +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/db913959c675cea6.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/f061a4be97bfc3b3.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/f2e7afeab1178138.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/f7d1a90dd75d2572.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/ff1a16fafef87110.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/__next._not-found.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/__next._not-found.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/__next.contracts.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/__next.contracts.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/__next.documentation.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/__next.documentation.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/__next.metadata.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/__next.metadata.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/__next.quality.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/__next.quality.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/__next.rules.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/__next.rules.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/__next.schemas.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/__next.schemas.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/__next.settings.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/__next.settings.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/.gitkeep +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/404/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/404.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/__next.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/0rYA78L88aUyD2Uh38hhX/_buildManifest.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/0rYA78L88aUyD2Uh38hhX/_ssgManifest.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/13d4a0fbd74c1ee4.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/222442f6da32302a.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/247eb132b7f7b574.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/297d55555b71baba.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/2ab439ce003cd691.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/2edb43b48432ac04.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/414e77373f8ff61c.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/49ca65abd26ae49e.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/5e04d10c4a7b58a3.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/652ad0aa26265c47.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/75d88a058d8ffaa6.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/8c89634cf6bad76f.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/9667e7a3d359eb39.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/9c23f44fff36548a.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/a6dad97d9634a72d.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/b32a0963684b9933.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/c4fa4f4114b7c352.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/c69f6cba366bd988.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/d2363397e1b2bcab.css +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/db913959c675cea6.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/f061a4be97bfc3b3.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/f2e7afeab1178138.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/f7d1a90dd75d2572.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/ff1a16fafef87110.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/__next._not-found.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/__next._not-found.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/__next.contracts.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/__next.contracts.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/__next.documentation.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/__next.documentation.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/__next.metadata.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/__next.metadata.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/__next.quality.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/__next.quality.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/__next.rules.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/__next.rules.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/__next.schemas.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/__next.schemas.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/__next.settings.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/__next.settings.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/.gitkeep +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/404/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/404.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/__next.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/222442f6da32302a.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/247eb132b7f7b574.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/297d55555b71baba.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/2ab439ce003cd691.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/414e77373f8ff61c.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/49ca65abd26ae49e.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/4e310fe5005770a3.css +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/5e04d10c4a7b58a3.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/5fc14c00a2779dc5.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/652ad0aa26265c47.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/75d88a058d8ffaa6.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/8c89634cf6bad76f.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/9667e7a3d359eb39.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/9c23f44fff36548a.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/a6dad97d9634a72d.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/b32a0963684b9933.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/b584574fdc8ab13e.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/c69f6cba366bd988.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/d5989c94d3614b3a.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/db913959c675cea6.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/f061a4be97bfc3b3.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/f2e7afeab1178138.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/ff1a16fafef87110.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_buildManifest.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_ssgManifest.js +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/__next._not-found.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/__next._not-found.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/__next.contracts.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/__next.contracts.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/__next.documentation.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/__next.documentation.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/__next.metadata.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/__next.metadata.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/__next.quality.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/__next.quality.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/__next.rules.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/__next.rules.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/__next.schemas.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/__next.schemas.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/__next.settings.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/__next.settings.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/__next.validation.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/__next.validation.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/__next.validation.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/__next.validation.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/__next._full.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/__next._head.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/__next._index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/__next._tree.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/__next.validation.__PAGE__.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/__next.validation.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/index.html +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/index.txt +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/worker/__init__.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/worker/cli.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/worker/models.py +0 -0
- {pycharter-0.0.23 → pycharter-0.0.24}/worker/processor.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycharter
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.24
|
|
4
4
|
Summary: A Python package for data contract management with five core services: contract parsing, metadata storage, Pydantic generation, JSON Schema conversion, and runtime validation
|
|
5
5
|
Author-email: semantic developers <na@example.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -164,6 +164,41 @@ pycharter ui dev # Development mode with hot reload
|
|
|
164
164
|
|
|
165
165
|
## 🚀 Quick Start
|
|
166
166
|
|
|
167
|
+
### Quick Start: ETL Pipelines
|
|
168
|
+
|
|
169
|
+
Build and run ETL pipelines programmatically (with the `|` operator) or from YAML configs. Pipeline **run()** is async; use `asyncio.run()` from scripts or `await` in async code.
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
import asyncio
|
|
173
|
+
from pycharter import Pipeline, HTTPExtractor, PostgresLoader, Rename, AddField
|
|
174
|
+
|
|
175
|
+
# Programmatic pipeline
|
|
176
|
+
pipeline = (
|
|
177
|
+
Pipeline(HTTPExtractor(url="https://api.example.com/data"))
|
|
178
|
+
| Rename({"old": "new"})
|
|
179
|
+
| AddField("processed_at", "now()")
|
|
180
|
+
| PostgresLoader(connection_string="...", table="users")
|
|
181
|
+
)
|
|
182
|
+
result = asyncio.run(pipeline.run())
|
|
183
|
+
|
|
184
|
+
# Config-driven: explicit files
|
|
185
|
+
pipeline = Pipeline.from_config_files(
|
|
186
|
+
extract="configs/extract.yaml",
|
|
187
|
+
load="configs/load.yaml",
|
|
188
|
+
variables={"API_KEY": "secret"}
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
# Config-driven: directory (extract.yaml, transform.yaml, load.yaml)
|
|
192
|
+
pipeline = Pipeline.from_config_dir("pipelines/users/")
|
|
193
|
+
|
|
194
|
+
# Config-driven: single file
|
|
195
|
+
pipeline = Pipeline.from_config_file("pipelines/users/pipeline.yaml")
|
|
196
|
+
|
|
197
|
+
result = asyncio.run(pipeline.run())
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
See **ETL Pipelines** under Core Services for error handling (`error_context`, `ErrorMode`) and variable resolution (`PipelineContext(variables={...})`).
|
|
201
|
+
|
|
167
202
|
### Quick Start: Convenience Functions (One-off Use)
|
|
168
203
|
|
|
169
204
|
```python
|
|
@@ -192,14 +227,29 @@ if result.is_valid:
|
|
|
192
227
|
|
|
193
228
|
### Production Use: Validator Class (Recommended)
|
|
194
229
|
|
|
195
|
-
For production code with multiple validations, use the `Validator` class for better performance:
|
|
230
|
+
For production code with multiple validations, use the `Validator` class for better performance. Create validators via **factory methods** or from a metadata store:
|
|
196
231
|
|
|
197
232
|
```python
|
|
198
233
|
from pycharter import Validator
|
|
199
234
|
|
|
200
|
-
#
|
|
201
|
-
validator = Validator(
|
|
202
|
-
|
|
235
|
+
# From directory (expects schema.yaml, coercion_rules.yaml, validation_rules.yaml)
|
|
236
|
+
validator = Validator.from_dir("data/contracts/user")
|
|
237
|
+
|
|
238
|
+
# From explicit files (any filenames)
|
|
239
|
+
validator = Validator.from_files(
|
|
240
|
+
schema="schemas/user.yaml",
|
|
241
|
+
coercion_rules="rules/coercion.yaml",
|
|
242
|
+
validation_rules="rules/validation.yaml"
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
# From a single contract file
|
|
246
|
+
validator = Validator.from_file("user_contract.yaml")
|
|
247
|
+
|
|
248
|
+
# From dictionaries
|
|
249
|
+
validator = Validator.from_dict(schema={...}, coercion_rules={...}, validation_rules={...})
|
|
250
|
+
|
|
251
|
+
# From metadata store (with database)
|
|
252
|
+
validator = Validator(store=store, schema_id="user_schema_v1")
|
|
203
253
|
|
|
204
254
|
# Validate multiple records efficiently (model is cached)
|
|
205
255
|
result1 = validator.validate({"name": "Alice", "age": 30})
|
|
@@ -232,11 +282,12 @@ PyCharter's API is organized into **three tiers** to help you choose the right a
|
|
|
232
282
|
### Tier 1: Primary Interfaces (⭐ Recommended for Production)
|
|
233
283
|
|
|
234
284
|
**Classes** that provide the best performance and most features:
|
|
235
|
-
- **`Validator`** - Primary validation interface (use for multiple validations)
|
|
285
|
+
- **`Validator`** - Primary validation interface (use for multiple validations); create via `from_dir()`, `from_files()`, `from_file()`, `from_dict()` or from store
|
|
286
|
+
- **`Pipeline`** - ETL pipeline (programmatic or config-driven); create via `from_config_files()`, `from_config_dir()`, `from_config_file()` or constructor
|
|
236
287
|
- **`QualityCheck`** - Primary quality assurance interface
|
|
237
288
|
- **`MetadataStoreClient`** - Base class for metadata stores
|
|
238
289
|
|
|
239
|
-
**When to use**: Production code, batch processing, when you need to validate multiple records.
|
|
290
|
+
**When to use**: Production code, batch processing, when you need to validate multiple records or run ETL pipelines.
|
|
240
291
|
|
|
241
292
|
### Tier 2: Convenience Functions (Quick Start)
|
|
242
293
|
|
|
@@ -530,20 +581,24 @@ PyCharter provides validation through three tiers:
|
|
|
530
581
|
```python
|
|
531
582
|
from pycharter import Validator, SQLiteMetadataStore
|
|
532
583
|
|
|
533
|
-
# Option 1: From
|
|
534
|
-
validator = Validator(
|
|
584
|
+
# Option 1: From directory (schema.yaml, coercion_rules.yaml, validation_rules.yaml)
|
|
585
|
+
validator = Validator.from_dir("data/contracts/user")
|
|
586
|
+
result = validator.validate({"name": "Alice", "age": 30})
|
|
587
|
+
|
|
588
|
+
# Option 2: From explicit files
|
|
589
|
+
validator = Validator.from_files(schema="schemas/user.yaml", coercion_rules="rules/coercion.yaml")
|
|
590
|
+
result = validator.validate({"name": "Alice", "age": 30})
|
|
591
|
+
|
|
592
|
+
# Option 3: From single contract file
|
|
593
|
+
validator = Validator.from_file("user_contract.yaml")
|
|
535
594
|
result = validator.validate({"name": "Alice", "age": 30})
|
|
536
595
|
|
|
537
|
-
# Option
|
|
596
|
+
# Option 4: From metadata store (with database)
|
|
538
597
|
store = SQLiteMetadataStore("metadata.db")
|
|
539
598
|
store.connect()
|
|
540
599
|
validator = Validator(store=store, schema_id="user_schema_v1")
|
|
541
600
|
result = validator.validate({"name": "Alice", "age": 30})
|
|
542
601
|
|
|
543
|
-
# Option 3: From contract file
|
|
544
|
-
validator = Validator(contract_file="user_contract.yaml")
|
|
545
|
-
result = validator.validate({"name": "Alice", "age": 30})
|
|
546
|
-
|
|
547
602
|
# Batch validation (efficient - model cached)
|
|
548
603
|
results = validator.validate_batch([data1, data2, data3])
|
|
549
604
|
```
|
|
@@ -584,6 +639,55 @@ results = validate_batch(UserModel, [data1, data2, data3])
|
|
|
584
639
|
|
|
585
640
|
---
|
|
586
641
|
|
|
642
|
+
### 5b. 🔄 ETL Pipelines (`pycharter.etl_generator`)
|
|
643
|
+
|
|
644
|
+
**Purpose**: Build and run ETL pipelines programmatically (with the `|` operator) or from YAML configs. No assumptions about project layout—you specify file paths or use a directory with standard filenames.
|
|
645
|
+
|
|
646
|
+
**When to Use**: When you need to extract, transform, and load data from config-driven or code-defined pipelines (HTTP, files, databases, cloud storage → transforms → Postgres, files, cloud).
|
|
647
|
+
|
|
648
|
+
**How It Works**:
|
|
649
|
+
- **Programmatic**: `Pipeline(extractor) | transformer | loader`; chain with `|`; call `await pipeline.run()`.
|
|
650
|
+
- **Config-driven**: Load from explicit files (`from_config_files`), from a directory with `extract.yaml`, `transform.yaml`, `load.yaml` (`from_config_dir`), or from a single `pipeline.yaml` (`from_config_file`).
|
|
651
|
+
- **Variables**: Pass `PipelineContext(variables={"API_KEY": "x"})` or `variables={...}` in factory methods; `${VAR}` and `${VAR:-default}` in configs are resolved from these (no built-in `CONTRACT_DIR`).
|
|
652
|
+
- **Async**: `run()` is async; use `asyncio.run(pipeline.run())` in scripts or `await pipeline.run()` in async code.
|
|
653
|
+
- **Error handling**: Optional `error_context` with `ErrorMode` (STRICT, LENIENT, COLLECT) controls whether extraction/load failures raise or are collected in `result.errors`.
|
|
654
|
+
|
|
655
|
+
**Example**:
|
|
656
|
+
```python
|
|
657
|
+
import asyncio
|
|
658
|
+
from pycharter import Pipeline, PipelineContext, HTTPExtractor, PostgresLoader, Rename, AddField
|
|
659
|
+
|
|
660
|
+
# Programmatic
|
|
661
|
+
pipeline = (
|
|
662
|
+
Pipeline(HTTPExtractor(url="https://api.example.com/users"))
|
|
663
|
+
| Rename({"userName": "name"})
|
|
664
|
+
| AddField("processed_at", "now()")
|
|
665
|
+
| PostgresLoader(connection_string="...", table="users")
|
|
666
|
+
)
|
|
667
|
+
result = asyncio.run(pipeline.run())
|
|
668
|
+
|
|
669
|
+
# Config-driven (explicit files)
|
|
670
|
+
pipeline = Pipeline.from_config_files(
|
|
671
|
+
extract="configs/extract.yaml",
|
|
672
|
+
load="configs/load.yaml",
|
|
673
|
+
variables={"API_KEY": "secret"}
|
|
674
|
+
)
|
|
675
|
+
|
|
676
|
+
# Config-driven (directory: extract.yaml, transform.yaml, load.yaml)
|
|
677
|
+
pipeline = Pipeline.from_config_dir("pipelines/users/")
|
|
678
|
+
|
|
679
|
+
# Config-driven (single file)
|
|
680
|
+
pipeline = Pipeline.from_config_file("pipelines/users/pipeline.yaml")
|
|
681
|
+
|
|
682
|
+
result = asyncio.run(pipeline.run())
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
**Exceptions**: Pipeline and config loading use PyCharter’s exception hierarchy: `PyCharterError` (base), `ConfigError`, `ConfigValidationError`, `ExpressionError`. See **Exceptions** under API Reference.
|
|
686
|
+
|
|
687
|
+
**See** `pycharter/etl_generator/ASYNC_AND_EXECUTION.md` for async usage and error modes.
|
|
688
|
+
|
|
689
|
+
---
|
|
690
|
+
|
|
587
691
|
### 6. 🔍 Quality Assurance (`pycharter.quality`)
|
|
588
692
|
|
|
589
693
|
**Purpose**: Data quality assurance pipeline that polices data according to data contracts, calculates quality metrics, tracks violations, and generates quality reports.
|
|
@@ -704,7 +808,7 @@ def process_user_data_quick(raw_data):
|
|
|
704
808
|
|
|
705
809
|
---
|
|
706
810
|
|
|
707
|
-
### 7. 🌐 REST API (`api/`)
|
|
811
|
+
### 7. 🌐 REST API (`api/`) (`api/`)
|
|
708
812
|
|
|
709
813
|
**Purpose**: Expose all PyCharter services as REST API endpoints.
|
|
710
814
|
|
|
@@ -752,6 +856,7 @@ See `api/README.md` for complete API documentation.
|
|
|
752
856
|
| **Pydantic Generator** | JSON Schema | Pydantic models | Storage → Model Generation |
|
|
753
857
|
| **JSON Schema Converter** | Pydantic models | JSON Schema | (Bidirectional) |
|
|
754
858
|
| **Runtime Validator** | Pydantic models + Data | `ValidationResult` | Model Generation → Validation |
|
|
859
|
+
| **ETL Pipelines** | Config files or code | `PipelineResult` | Extract → Transform → Load |
|
|
755
860
|
| **Quality Assurance** | Contract + Data | `QualityReport` | Validation → Quality Monitoring |
|
|
756
861
|
|
|
757
862
|
Each service is designed to be **independent** yet **composable**, allowing you to use them individually or together as part of a complete data contract management system.
|
|
@@ -795,12 +900,9 @@ Product = from_file("product_schema.json", "Product")
|
|
|
795
900
|
```python
|
|
796
901
|
from pycharter import Validator
|
|
797
902
|
|
|
798
|
-
# From
|
|
799
|
-
validator = Validator(
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
# From contract file
|
|
803
|
-
validator = Validator(contract_file="article_contract.yaml")
|
|
903
|
+
# From directory or single file
|
|
904
|
+
validator = Validator.from_dir("data/contracts/article")
|
|
905
|
+
# or: validator = Validator.from_file("article_contract.yaml")
|
|
804
906
|
result = validator.validate({"title": "My Article", "published": True})
|
|
805
907
|
```
|
|
806
908
|
|
|
@@ -1019,11 +1121,12 @@ PyCharter's API is organized into three tiers to help you choose the right appro
|
|
|
1019
1121
|
```python
|
|
1020
1122
|
from pycharter import Validator
|
|
1021
1123
|
|
|
1022
|
-
# Create validator
|
|
1023
|
-
validator = Validator(
|
|
1024
|
-
validator = Validator(
|
|
1025
|
-
validator = Validator(
|
|
1026
|
-
validator = Validator(
|
|
1124
|
+
# Create validator via factory methods or store
|
|
1125
|
+
validator = Validator.from_dir("data/contracts/user")
|
|
1126
|
+
validator = Validator.from_files(schema="schema.yaml", coercion_rules="coercion.yaml")
|
|
1127
|
+
validator = Validator.from_file("contract.yaml")
|
|
1128
|
+
validator = Validator.from_dict(schema={...}, coercion_rules={...})
|
|
1129
|
+
validator = Validator(store=store, schema_id="user_schema") # from metadata store
|
|
1027
1130
|
|
|
1028
1131
|
# Validate data
|
|
1029
1132
|
result = validator.validate(data)
|
|
@@ -1094,6 +1197,18 @@ store.connect()
|
|
|
1094
1197
|
- **`MongoDBMetadataStore(connection_string: str)`** - MongoDB database
|
|
1095
1198
|
- **`RedisMetadataStore(connection_string: str)`** - Redis database
|
|
1096
1199
|
|
|
1200
|
+
### Exceptions
|
|
1201
|
+
|
|
1202
|
+
PyCharter uses a small exception hierarchy for config and pipeline errors. Catch **`PyCharterError`** to handle any PyCharter failure:
|
|
1203
|
+
|
|
1204
|
+
- **`PyCharterError`** - Base for all PyCharter exceptions
|
|
1205
|
+
- **`ConfigError`** - Config loading/parsing failures (missing file, invalid YAML)
|
|
1206
|
+
- **`ConfigValidationError`** - Schema validation failures (e.g. missing required `type` field)
|
|
1207
|
+
- **`ConfigLoadError`** - Config file load errors
|
|
1208
|
+
- **`ExpressionError`** - Expression evaluation failures (e.g. invalid syntax in AddField)
|
|
1209
|
+
|
|
1210
|
+
Pipeline **`run(error_context=...)`** supports **`ErrorMode`**: **STRICT** (raise on failure), **LENIENT** (log and continue), **COLLECT** (append to `result.errors`). Import from `pycharter.shared.errors`.
|
|
1211
|
+
|
|
1097
1212
|
## 🎯 Design Principles & Requirements
|
|
1098
1213
|
|
|
1099
1214
|
Charter is designed to meet the following core requirements:
|
|
@@ -101,6 +101,41 @@ pycharter ui dev # Development mode with hot reload
|
|
|
101
101
|
|
|
102
102
|
## 🚀 Quick Start
|
|
103
103
|
|
|
104
|
+
### Quick Start: ETL Pipelines
|
|
105
|
+
|
|
106
|
+
Build and run ETL pipelines programmatically (with the `|` operator) or from YAML configs. Pipeline **run()** is async; use `asyncio.run()` from scripts or `await` in async code.
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
import asyncio
|
|
110
|
+
from pycharter import Pipeline, HTTPExtractor, PostgresLoader, Rename, AddField
|
|
111
|
+
|
|
112
|
+
# Programmatic pipeline
|
|
113
|
+
pipeline = (
|
|
114
|
+
Pipeline(HTTPExtractor(url="https://api.example.com/data"))
|
|
115
|
+
| Rename({"old": "new"})
|
|
116
|
+
| AddField("processed_at", "now()")
|
|
117
|
+
| PostgresLoader(connection_string="...", table="users")
|
|
118
|
+
)
|
|
119
|
+
result = asyncio.run(pipeline.run())
|
|
120
|
+
|
|
121
|
+
# Config-driven: explicit files
|
|
122
|
+
pipeline = Pipeline.from_config_files(
|
|
123
|
+
extract="configs/extract.yaml",
|
|
124
|
+
load="configs/load.yaml",
|
|
125
|
+
variables={"API_KEY": "secret"}
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Config-driven: directory (extract.yaml, transform.yaml, load.yaml)
|
|
129
|
+
pipeline = Pipeline.from_config_dir("pipelines/users/")
|
|
130
|
+
|
|
131
|
+
# Config-driven: single file
|
|
132
|
+
pipeline = Pipeline.from_config_file("pipelines/users/pipeline.yaml")
|
|
133
|
+
|
|
134
|
+
result = asyncio.run(pipeline.run())
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
See **ETL Pipelines** under Core Services for error handling (`error_context`, `ErrorMode`) and variable resolution (`PipelineContext(variables={...})`).
|
|
138
|
+
|
|
104
139
|
### Quick Start: Convenience Functions (One-off Use)
|
|
105
140
|
|
|
106
141
|
```python
|
|
@@ -129,14 +164,29 @@ if result.is_valid:
|
|
|
129
164
|
|
|
130
165
|
### Production Use: Validator Class (Recommended)
|
|
131
166
|
|
|
132
|
-
For production code with multiple validations, use the `Validator` class for better performance:
|
|
167
|
+
For production code with multiple validations, use the `Validator` class for better performance. Create validators via **factory methods** or from a metadata store:
|
|
133
168
|
|
|
134
169
|
```python
|
|
135
170
|
from pycharter import Validator
|
|
136
171
|
|
|
137
|
-
#
|
|
138
|
-
validator = Validator(
|
|
139
|
-
|
|
172
|
+
# From directory (expects schema.yaml, coercion_rules.yaml, validation_rules.yaml)
|
|
173
|
+
validator = Validator.from_dir("data/contracts/user")
|
|
174
|
+
|
|
175
|
+
# From explicit files (any filenames)
|
|
176
|
+
validator = Validator.from_files(
|
|
177
|
+
schema="schemas/user.yaml",
|
|
178
|
+
coercion_rules="rules/coercion.yaml",
|
|
179
|
+
validation_rules="rules/validation.yaml"
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
# From a single contract file
|
|
183
|
+
validator = Validator.from_file("user_contract.yaml")
|
|
184
|
+
|
|
185
|
+
# From dictionaries
|
|
186
|
+
validator = Validator.from_dict(schema={...}, coercion_rules={...}, validation_rules={...})
|
|
187
|
+
|
|
188
|
+
# From metadata store (with database)
|
|
189
|
+
validator = Validator(store=store, schema_id="user_schema_v1")
|
|
140
190
|
|
|
141
191
|
# Validate multiple records efficiently (model is cached)
|
|
142
192
|
result1 = validator.validate({"name": "Alice", "age": 30})
|
|
@@ -169,11 +219,12 @@ PyCharter's API is organized into **three tiers** to help you choose the right a
|
|
|
169
219
|
### Tier 1: Primary Interfaces (⭐ Recommended for Production)
|
|
170
220
|
|
|
171
221
|
**Classes** that provide the best performance and most features:
|
|
172
|
-
- **`Validator`** - Primary validation interface (use for multiple validations)
|
|
222
|
+
- **`Validator`** - Primary validation interface (use for multiple validations); create via `from_dir()`, `from_files()`, `from_file()`, `from_dict()` or from store
|
|
223
|
+
- **`Pipeline`** - ETL pipeline (programmatic or config-driven); create via `from_config_files()`, `from_config_dir()`, `from_config_file()` or constructor
|
|
173
224
|
- **`QualityCheck`** - Primary quality assurance interface
|
|
174
225
|
- **`MetadataStoreClient`** - Base class for metadata stores
|
|
175
226
|
|
|
176
|
-
**When to use**: Production code, batch processing, when you need to validate multiple records.
|
|
227
|
+
**When to use**: Production code, batch processing, when you need to validate multiple records or run ETL pipelines.
|
|
177
228
|
|
|
178
229
|
### Tier 2: Convenience Functions (Quick Start)
|
|
179
230
|
|
|
@@ -467,20 +518,24 @@ PyCharter provides validation through three tiers:
|
|
|
467
518
|
```python
|
|
468
519
|
from pycharter import Validator, SQLiteMetadataStore
|
|
469
520
|
|
|
470
|
-
# Option 1: From
|
|
471
|
-
validator = Validator(
|
|
521
|
+
# Option 1: From directory (schema.yaml, coercion_rules.yaml, validation_rules.yaml)
|
|
522
|
+
validator = Validator.from_dir("data/contracts/user")
|
|
523
|
+
result = validator.validate({"name": "Alice", "age": 30})
|
|
524
|
+
|
|
525
|
+
# Option 2: From explicit files
|
|
526
|
+
validator = Validator.from_files(schema="schemas/user.yaml", coercion_rules="rules/coercion.yaml")
|
|
527
|
+
result = validator.validate({"name": "Alice", "age": 30})
|
|
528
|
+
|
|
529
|
+
# Option 3: From single contract file
|
|
530
|
+
validator = Validator.from_file("user_contract.yaml")
|
|
472
531
|
result = validator.validate({"name": "Alice", "age": 30})
|
|
473
532
|
|
|
474
|
-
# Option
|
|
533
|
+
# Option 4: From metadata store (with database)
|
|
475
534
|
store = SQLiteMetadataStore("metadata.db")
|
|
476
535
|
store.connect()
|
|
477
536
|
validator = Validator(store=store, schema_id="user_schema_v1")
|
|
478
537
|
result = validator.validate({"name": "Alice", "age": 30})
|
|
479
538
|
|
|
480
|
-
# Option 3: From contract file
|
|
481
|
-
validator = Validator(contract_file="user_contract.yaml")
|
|
482
|
-
result = validator.validate({"name": "Alice", "age": 30})
|
|
483
|
-
|
|
484
539
|
# Batch validation (efficient - model cached)
|
|
485
540
|
results = validator.validate_batch([data1, data2, data3])
|
|
486
541
|
```
|
|
@@ -521,6 +576,55 @@ results = validate_batch(UserModel, [data1, data2, data3])
|
|
|
521
576
|
|
|
522
577
|
---
|
|
523
578
|
|
|
579
|
+
### 5b. 🔄 ETL Pipelines (`pycharter.etl_generator`)
|
|
580
|
+
|
|
581
|
+
**Purpose**: Build and run ETL pipelines programmatically (with the `|` operator) or from YAML configs. No assumptions about project layout—you specify file paths or use a directory with standard filenames.
|
|
582
|
+
|
|
583
|
+
**When to Use**: When you need to extract, transform, and load data from config-driven or code-defined pipelines (HTTP, files, databases, cloud storage → transforms → Postgres, files, cloud).
|
|
584
|
+
|
|
585
|
+
**How It Works**:
|
|
586
|
+
- **Programmatic**: `Pipeline(extractor) | transformer | loader`; chain with `|`; call `await pipeline.run()`.
|
|
587
|
+
- **Config-driven**: Load from explicit files (`from_config_files`), from a directory with `extract.yaml`, `transform.yaml`, `load.yaml` (`from_config_dir`), or from a single `pipeline.yaml` (`from_config_file`).
|
|
588
|
+
- **Variables**: Pass `PipelineContext(variables={"API_KEY": "x"})` or `variables={...}` in factory methods; `${VAR}` and `${VAR:-default}` in configs are resolved from these (no built-in `CONTRACT_DIR`).
|
|
589
|
+
- **Async**: `run()` is async; use `asyncio.run(pipeline.run())` in scripts or `await pipeline.run()` in async code.
|
|
590
|
+
- **Error handling**: Optional `error_context` with `ErrorMode` (STRICT, LENIENT, COLLECT) controls whether extraction/load failures raise or are collected in `result.errors`.
|
|
591
|
+
|
|
592
|
+
**Example**:
|
|
593
|
+
```python
|
|
594
|
+
import asyncio
|
|
595
|
+
from pycharter import Pipeline, PipelineContext, HTTPExtractor, PostgresLoader, Rename, AddField
|
|
596
|
+
|
|
597
|
+
# Programmatic
|
|
598
|
+
pipeline = (
|
|
599
|
+
Pipeline(HTTPExtractor(url="https://api.example.com/users"))
|
|
600
|
+
| Rename({"userName": "name"})
|
|
601
|
+
| AddField("processed_at", "now()")
|
|
602
|
+
| PostgresLoader(connection_string="...", table="users")
|
|
603
|
+
)
|
|
604
|
+
result = asyncio.run(pipeline.run())
|
|
605
|
+
|
|
606
|
+
# Config-driven (explicit files)
|
|
607
|
+
pipeline = Pipeline.from_config_files(
|
|
608
|
+
extract="configs/extract.yaml",
|
|
609
|
+
load="configs/load.yaml",
|
|
610
|
+
variables={"API_KEY": "secret"}
|
|
611
|
+
)
|
|
612
|
+
|
|
613
|
+
# Config-driven (directory: extract.yaml, transform.yaml, load.yaml)
|
|
614
|
+
pipeline = Pipeline.from_config_dir("pipelines/users/")
|
|
615
|
+
|
|
616
|
+
# Config-driven (single file)
|
|
617
|
+
pipeline = Pipeline.from_config_file("pipelines/users/pipeline.yaml")
|
|
618
|
+
|
|
619
|
+
result = asyncio.run(pipeline.run())
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
**Exceptions**: Pipeline and config loading use PyCharter’s exception hierarchy: `PyCharterError` (base), `ConfigError`, `ConfigValidationError`, `ExpressionError`. See **Exceptions** under API Reference.
|
|
623
|
+
|
|
624
|
+
**See** `pycharter/etl_generator/ASYNC_AND_EXECUTION.md` for async usage and error modes.
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
524
628
|
### 6. 🔍 Quality Assurance (`pycharter.quality`)
|
|
525
629
|
|
|
526
630
|
**Purpose**: Data quality assurance pipeline that polices data according to data contracts, calculates quality metrics, tracks violations, and generates quality reports.
|
|
@@ -641,7 +745,7 @@ def process_user_data_quick(raw_data):
|
|
|
641
745
|
|
|
642
746
|
---
|
|
643
747
|
|
|
644
|
-
### 7. 🌐 REST API (`api/`)
|
|
748
|
+
### 7. 🌐 REST API (`api/`) (`api/`)
|
|
645
749
|
|
|
646
750
|
**Purpose**: Expose all PyCharter services as REST API endpoints.
|
|
647
751
|
|
|
@@ -689,6 +793,7 @@ See `api/README.md` for complete API documentation.
|
|
|
689
793
|
| **Pydantic Generator** | JSON Schema | Pydantic models | Storage → Model Generation |
|
|
690
794
|
| **JSON Schema Converter** | Pydantic models | JSON Schema | (Bidirectional) |
|
|
691
795
|
| **Runtime Validator** | Pydantic models + Data | `ValidationResult` | Model Generation → Validation |
|
|
796
|
+
| **ETL Pipelines** | Config files or code | `PipelineResult` | Extract → Transform → Load |
|
|
692
797
|
| **Quality Assurance** | Contract + Data | `QualityReport` | Validation → Quality Monitoring |
|
|
693
798
|
|
|
694
799
|
Each service is designed to be **independent** yet **composable**, allowing you to use them individually or together as part of a complete data contract management system.
|
|
@@ -732,12 +837,9 @@ Product = from_file("product_schema.json", "Product")
|
|
|
732
837
|
```python
|
|
733
838
|
from pycharter import Validator
|
|
734
839
|
|
|
735
|
-
# From
|
|
736
|
-
validator = Validator(
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
# From contract file
|
|
740
|
-
validator = Validator(contract_file="article_contract.yaml")
|
|
840
|
+
# From directory or single file
|
|
841
|
+
validator = Validator.from_dir("data/contracts/article")
|
|
842
|
+
# or: validator = Validator.from_file("article_contract.yaml")
|
|
741
843
|
result = validator.validate({"title": "My Article", "published": True})
|
|
742
844
|
```
|
|
743
845
|
|
|
@@ -956,11 +1058,12 @@ PyCharter's API is organized into three tiers to help you choose the right appro
|
|
|
956
1058
|
```python
|
|
957
1059
|
from pycharter import Validator
|
|
958
1060
|
|
|
959
|
-
# Create validator
|
|
960
|
-
validator = Validator(
|
|
961
|
-
validator = Validator(
|
|
962
|
-
validator = Validator(
|
|
963
|
-
validator = Validator(
|
|
1061
|
+
# Create validator via factory methods or store
|
|
1062
|
+
validator = Validator.from_dir("data/contracts/user")
|
|
1063
|
+
validator = Validator.from_files(schema="schema.yaml", coercion_rules="coercion.yaml")
|
|
1064
|
+
validator = Validator.from_file("contract.yaml")
|
|
1065
|
+
validator = Validator.from_dict(schema={...}, coercion_rules={...})
|
|
1066
|
+
validator = Validator(store=store, schema_id="user_schema") # from metadata store
|
|
964
1067
|
|
|
965
1068
|
# Validate data
|
|
966
1069
|
result = validator.validate(data)
|
|
@@ -1031,6 +1134,18 @@ store.connect()
|
|
|
1031
1134
|
- **`MongoDBMetadataStore(connection_string: str)`** - MongoDB database
|
|
1032
1135
|
- **`RedisMetadataStore(connection_string: str)`** - Redis database
|
|
1033
1136
|
|
|
1137
|
+
### Exceptions
|
|
1138
|
+
|
|
1139
|
+
PyCharter uses a small exception hierarchy for config and pipeline errors. Catch **`PyCharterError`** to handle any PyCharter failure:
|
|
1140
|
+
|
|
1141
|
+
- **`PyCharterError`** - Base for all PyCharter exceptions
|
|
1142
|
+
- **`ConfigError`** - Config loading/parsing failures (missing file, invalid YAML)
|
|
1143
|
+
- **`ConfigValidationError`** - Schema validation failures (e.g. missing required `type` field)
|
|
1144
|
+
- **`ConfigLoadError`** - Config file load errors
|
|
1145
|
+
- **`ExpressionError`** - Expression evaluation failures (e.g. invalid syntax in AddField)
|
|
1146
|
+
|
|
1147
|
+
Pipeline **`run(error_context=...)`** supports **`ErrorMode`**: **STRICT** (raise on failure), **LENIENT** (log and continue), **COLLECT** (append to `result.errors`). Import from `pycharter.shared.errors`.
|
|
1148
|
+
|
|
1034
1149
|
## 🎯 Design Principles & Requirements
|
|
1035
1150
|
|
|
1036
1151
|
Charter is designed to meet the following core requirements:
|
|
@@ -16,7 +16,18 @@ from fastapi.routing import APIRoute
|
|
|
16
16
|
from pycharter import __version__ as pycharter_version
|
|
17
17
|
|
|
18
18
|
# Import routers from v1
|
|
19
|
-
from api.routes.v1 import
|
|
19
|
+
from api.routes.v1 import (
|
|
20
|
+
contracts,
|
|
21
|
+
metadata,
|
|
22
|
+
quality,
|
|
23
|
+
schemas,
|
|
24
|
+
templates,
|
|
25
|
+
validation,
|
|
26
|
+
settings,
|
|
27
|
+
docs,
|
|
28
|
+
tracking,
|
|
29
|
+
evolution,
|
|
30
|
+
)
|
|
20
31
|
|
|
21
32
|
# Try to import validation_jobs router (requires worker component)
|
|
22
33
|
try:
|
|
@@ -128,6 +139,21 @@ def create_application() -> FastAPI:
|
|
|
128
139
|
prefix=f"/api/{API_VERSION}",
|
|
129
140
|
tags=["Settings"],
|
|
130
141
|
)
|
|
142
|
+
app.include_router(
|
|
143
|
+
docs.router,
|
|
144
|
+
prefix=f"/api/{API_VERSION}",
|
|
145
|
+
tags=["Documentation"],
|
|
146
|
+
)
|
|
147
|
+
app.include_router(
|
|
148
|
+
tracking.router,
|
|
149
|
+
prefix=f"/api/{API_VERSION}",
|
|
150
|
+
tags=["Quality Tracking"],
|
|
151
|
+
)
|
|
152
|
+
app.include_router(
|
|
153
|
+
evolution.router,
|
|
154
|
+
prefix=f"/api/{API_VERSION}",
|
|
155
|
+
tags=["Schema Evolution"],
|
|
156
|
+
)
|
|
131
157
|
|
|
132
158
|
# Include validation_jobs router if worker component is available
|
|
133
159
|
if VALIDATION_JOBS_AVAILABLE:
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
API models for documentation generation endpoints.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from enum import Enum
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DocsFormat(str, Enum):
|
|
12
|
+
"""Supported documentation output formats."""
|
|
13
|
+
|
|
14
|
+
MARKDOWN = "markdown"
|
|
15
|
+
HTML = "html"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class DocsRequest(BaseModel):
|
|
19
|
+
"""Request model for generating documentation from contract data."""
|
|
20
|
+
|
|
21
|
+
contract: dict = Field(..., description="Contract data to generate documentation for")
|
|
22
|
+
format: DocsFormat = Field(
|
|
23
|
+
default=DocsFormat.MARKDOWN, description="Output format for documentation"
|
|
24
|
+
)
|
|
25
|
+
include_schema: bool = Field(default=True, description="Include schema fields section")
|
|
26
|
+
include_coercions: bool = Field(
|
|
27
|
+
default=True, description="Include coercion rules section"
|
|
28
|
+
)
|
|
29
|
+
include_validations: bool = Field(
|
|
30
|
+
default=True, description="Include validation rules section"
|
|
31
|
+
)
|
|
32
|
+
include_metadata: bool = Field(
|
|
33
|
+
default=True, description="Include metadata/ownership section"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class DocsResponse(BaseModel):
|
|
38
|
+
"""Response model for generated documentation."""
|
|
39
|
+
|
|
40
|
+
documentation: str = Field(..., description="Generated documentation content")
|
|
41
|
+
format: DocsFormat = Field(..., description="Format of the generated documentation")
|
|
42
|
+
schema_name: Optional[str] = Field(
|
|
43
|
+
default=None, description="Name of the schema documented"
|
|
44
|
+
)
|
|
45
|
+
version: Optional[str] = Field(
|
|
46
|
+
default=None, description="Version of the schema documented"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class DocsSectionRequest(BaseModel):
|
|
51
|
+
"""Request model for generating a specific documentation section."""
|
|
52
|
+
|
|
53
|
+
contract: dict = Field(..., description="Contract data to generate documentation for")
|
|
54
|
+
section: str = Field(
|
|
55
|
+
...,
|
|
56
|
+
description="Section to generate: 'schema', 'coercions', 'validations', 'metadata'",
|
|
57
|
+
)
|
|
58
|
+
format: DocsFormat = Field(
|
|
59
|
+
default=DocsFormat.MARKDOWN, description="Output format for documentation"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class DocsSectionResponse(BaseModel):
|
|
64
|
+
"""Response model for a documentation section."""
|
|
65
|
+
|
|
66
|
+
section: str = Field(..., description="Name of the section generated")
|
|
67
|
+
content: str = Field(..., description="Generated section content")
|
|
68
|
+
format: DocsFormat = Field(..., description="Format of the generated content")
|