datacontract-cli 0.10.34__tar.gz → 0.10.35__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.
Potentially problematic release.
This version of datacontract-cli might be problematic. Click here for more details.
- {datacontract_cli-0.10.34/datacontract_cli.egg-info → datacontract_cli-0.10.35}/PKG-INFO +44 -35
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/README.md +38 -29
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/api.py +9 -2
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/cli.py +4 -2
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/fastjsonschema/check_jsonschema.py +29 -19
- datacontract_cli-0.10.35/datacontract/export/dqx_converter.py +121 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/exporter.py +1 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/exporter_factory.py +6 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/mermaid_exporter.py +24 -11
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/spark_converter.py +28 -3
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/odcs_v3_importer.py +29 -1
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35/datacontract_cli.egg-info}/PKG-INFO +44 -35
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract_cli.egg-info/SOURCES.txt +3 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract_cli.egg-info/requires.txt +5 -5
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/pyproject.toml +6 -6
- datacontract_cli-0.10.35/tests/test_export_dqx.py +319 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_spark.py +3 -2
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_spark.py +1 -1
- datacontract_cli-0.10.35/tests/test_test_local_json_nd.py +19 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/LICENSE +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/MANIFEST.in +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/__init__.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/breaking/breaking.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/breaking/breaking_change.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/breaking/breaking_rules.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/catalog/catalog.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/data_contract.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/__init__.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/data_contract_checks.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/data_contract_test.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/datacontract/check_that_datacontract_contains_valid_servers_configuration.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/datacontract/check_that_datacontract_file_exists.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/fastjsonschema/s3/s3_read_files.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/soda/__init__.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/soda/check_soda_execute.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/soda/connections/athena.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/soda/connections/bigquery.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/soda/connections/databricks.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/soda/connections/duckdb_connection.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/soda/connections/kafka.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/soda/connections/postgres.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/soda/connections/snowflake.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/soda/connections/sqlserver.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/engines/soda/connections/trino.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/__init__.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/avro_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/avro_idl_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/bigquery_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/custom_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/data_caterer_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/dbml_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/dbt_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/dcs_exporter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/duckdb_type_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/excel_exporter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/go_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/great_expectations_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/html_exporter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/iceberg_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/jsonschema_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/markdown_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/odcs_v3_exporter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/pandas_type_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/protobuf_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/pydantic_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/rdf_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/sodacl_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/sql_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/sql_type_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/sqlalchemy_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/terraform_converter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/avro_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/bigquery_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/csv_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/dbml_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/dbt_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/excel_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/glue_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/iceberg_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/importer_factory.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/json_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/jsonschema_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/odcs_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/parquet_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/protobuf_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/spark_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/sql_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/imports/unity_importer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/init/init_template.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/integration/datamesh_manager.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/lint/files.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/lint/lint.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/lint/linters/__init__.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/lint/linters/description_linter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/lint/linters/field_pattern_linter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/lint/linters/field_reference_linter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/lint/linters/notice_period_linter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/lint/linters/valid_constraints_linter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/lint/resolve.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/lint/resources.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/lint/schema.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/lint/urls.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/model/data_contract_specification/__init__.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/model/exceptions.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/model/odcs.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/model/run.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/output/__init__.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/output/junit_test_results.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/output/output_format.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/output/test_results_writer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/py.typed +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/schemas/datacontract-1.1.0.init.yaml +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/schemas/datacontract-1.1.0.schema.json +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/schemas/datacontract-1.2.0.init.yaml +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/schemas/datacontract-1.2.0.schema.json +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/schemas/odcs-3.0.1.schema.json +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/templates/datacontract.html +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/templates/datacontract_odcs.html +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/templates/index.html +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/templates/partials/datacontract_information.html +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/templates/partials/datacontract_servicelevels.html +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/templates/partials/datacontract_terms.html +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/templates/partials/definition.html +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/templates/partials/example.html +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/templates/partials/model_field.html +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/templates/partials/quality.html +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/templates/partials/server.html +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/templates/style/output.css +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract_cli.egg-info/dependency_links.txt +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract_cli.egg-info/entry_points.txt +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract_cli.egg-info/top_level.txt +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/setup.cfg +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_api.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_breaking.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_catalog.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_changelog.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_cli.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_data_contract_checks.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_data_contract_specification.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_description_linter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_documentation_linter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_download_datacontract_file.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_duckdb_json.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_avro.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_avro_idl.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_bigquery.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_complex_data_contract.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_custom.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_custom_exporter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_data_caterer.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_dbml.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_dbt_models.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_dbt_sources.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_dbt_staging_sql.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_excel.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_go.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_great_expectations.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_html.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_iceberg.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_jsonschema.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_markdown.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_mermaid.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_odcs_v3.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_protobuf.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_pydantic.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_rdf.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_sodacl.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_sql.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_sql_query.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_sqlalchemy.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_export_terraform.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_field_constraint_linter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_field_pattern_linter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_field_reference_linter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_avro.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_bigquery.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_csv.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_dbml.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_dbt.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_excel.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_glue.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_iceberg.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_json.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_jsonschema.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_odcs_v3.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_parquet.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_protobuf.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_sql_postgres.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_sql_sqlserver.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_import_unity_file.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_integration_datameshmanager.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_lint.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_notice_period_linter.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_resolve.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_roundtrip_jsonschema.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_spec_fields_field.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_spec_ref.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_api.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_athena_iceberg.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_azure_remote.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_bigquery.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_databricks.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_dataframe.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_delta.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_gcs_csv_remote.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_gcs_json_remote.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_kafka.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_kafka_remote.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_local_json.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_output_junit.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_parquet.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_postgres.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_quality.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_s3_csv.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_s3_delta.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_s3_json.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_s3_json_complex.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_s3_json_multiple_models.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_s3_json_remote.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_snowflake.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_sqlserver.py +0 -0
- {datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/tests/test_test_trino.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datacontract-cli
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.35
|
|
4
4
|
Summary: The datacontract CLI is an open source command-line tool for working with Data Contracts. It uses data contract YAML files to lint the data contract, connect to data sources and execute schema and quality tests, detect breaking changes, and export to different formats. The tool is written in Python. It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a Python library.
|
|
5
5
|
Author-email: Jochen Christ <jochen.christ@innoq.com>, Stefan Negele <stefan.negele@innoq.com>, Simon Harrer <simon.harrer@innoq.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -42,7 +42,7 @@ Provides-Extra: databricks
|
|
|
42
42
|
Requires-Dist: soda-core-spark-df<3.6.0,>=3.3.20; extra == "databricks"
|
|
43
43
|
Requires-Dist: soda-core-spark[databricks]<3.6.0,>=3.3.20; extra == "databricks"
|
|
44
44
|
Requires-Dist: databricks-sql-connector<4.1.0,>=3.7.0; extra == "databricks"
|
|
45
|
-
Requires-Dist: databricks-sdk<0.
|
|
45
|
+
Requires-Dist: databricks-sdk<0.64.0; extra == "databricks"
|
|
46
46
|
Requires-Dist: pyspark<4.0.0,>=3.5.5; extra == "databricks"
|
|
47
47
|
Provides-Extra: iceberg
|
|
48
48
|
Requires-Dist: pyiceberg==0.9.1; extra == "iceberg"
|
|
@@ -54,7 +54,7 @@ Provides-Extra: postgres
|
|
|
54
54
|
Requires-Dist: soda-core-postgres<3.6.0,>=3.3.20; extra == "postgres"
|
|
55
55
|
Provides-Extra: s3
|
|
56
56
|
Requires-Dist: s3fs<2026.0.0,>=2025.2.0; extra == "s3"
|
|
57
|
-
Requires-Dist: aiobotocore<2.
|
|
57
|
+
Requires-Dist: aiobotocore<2.25.0,>=2.17.0; extra == "s3"
|
|
58
58
|
Provides-Extra: snowflake
|
|
59
59
|
Requires-Dist: snowflake-connector-python[pandas]<3.17,>=3.6; extra == "snowflake"
|
|
60
60
|
Requires-Dist: soda-core-snowflake<3.6.0,>=3.3.20; extra == "snowflake"
|
|
@@ -83,15 +83,15 @@ Provides-Extra: dev
|
|
|
83
83
|
Requires-Dist: datacontract-cli[all]; extra == "dev"
|
|
84
84
|
Requires-Dist: httpx==0.28.1; extra == "dev"
|
|
85
85
|
Requires-Dist: kafka-python; extra == "dev"
|
|
86
|
-
Requires-Dist: moto==5.1.
|
|
86
|
+
Requires-Dist: moto==5.1.10; extra == "dev"
|
|
87
87
|
Requires-Dist: pandas>=2.1.0; extra == "dev"
|
|
88
|
-
Requires-Dist: pre-commit<4.
|
|
88
|
+
Requires-Dist: pre-commit<4.4.0,>=3.7.1; extra == "dev"
|
|
89
89
|
Requires-Dist: pytest; extra == "dev"
|
|
90
90
|
Requires-Dist: pytest-xdist; extra == "dev"
|
|
91
91
|
Requires-Dist: pymssql==2.3.7; extra == "dev"
|
|
92
92
|
Requires-Dist: ruff; extra == "dev"
|
|
93
93
|
Requires-Dist: testcontainers[kafka,minio,mssql,postgres]==4.12.0; extra == "dev"
|
|
94
|
-
Requires-Dist: trino==0.
|
|
94
|
+
Requires-Dist: trino==0.336.0; extra == "dev"
|
|
95
95
|
Dynamic: license-file
|
|
96
96
|
|
|
97
97
|
# Data Contract CLI
|
|
@@ -257,6 +257,14 @@ if not run.has_passed():
|
|
|
257
257
|
|
|
258
258
|
Choose the most appropriate installation method for your needs:
|
|
259
259
|
|
|
260
|
+
### uv
|
|
261
|
+
|
|
262
|
+
If you have [uv](https://docs.astral.sh/uv/) installed, you can run datacontract-cli directly without installing:
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
uv run --with 'datacontract-cli[all]' datacontract --version
|
|
266
|
+
```
|
|
267
|
+
|
|
260
268
|
### pip
|
|
261
269
|
Python 3.10, 3.11, and 3.12 are supported. We recommend to use Python 3.11.
|
|
262
270
|
|
|
@@ -1011,7 +1019,7 @@ models:
|
|
|
1011
1019
|
│ terraform|avro-idl|sql|sql-query|mer │
|
|
1012
1020
|
│ maid|html|go|bigquery|dbml|spark|sql │
|
|
1013
1021
|
│ alchemy|data-caterer|dcs|markdown|ic │
|
|
1014
|
-
│ eberg|custom|excel] │
|
|
1022
|
+
│ eberg|custom|excel|dqx] │
|
|
1015
1023
|
│ --output PATH Specify the file path where the │
|
|
1016
1024
|
│ exported data will be saved. If no │
|
|
1017
1025
|
│ path is provided, the output will be │
|
|
@@ -1057,35 +1065,36 @@ datacontract export --format html --output datacontract.html
|
|
|
1057
1065
|
|
|
1058
1066
|
Available export options:
|
|
1059
1067
|
|
|
1060
|
-
| Type | Description | Status
|
|
1061
|
-
|
|
1062
|
-
| `html` | Export to HTML | ✅
|
|
1063
|
-
| `jsonschema` | Export to JSON Schema | ✅
|
|
1064
|
-
| `odcs` | Export to Open Data Contract Standard (ODCS) V3 | ✅
|
|
1065
|
-
| `sodacl` | Export to SodaCL quality checks in YAML format | ✅
|
|
1066
|
-
| `dbt` | Export to dbt models in YAML format | ✅
|
|
1067
|
-
| `dbt-sources` | Export to dbt sources in YAML format | ✅
|
|
1068
|
-
| `dbt-staging-sql` | Export to dbt staging SQL models | ✅
|
|
1069
|
-
| `rdf` | Export data contract to RDF representation in N3 format | ✅
|
|
1070
|
-
| `avro` | Export to AVRO models | ✅
|
|
1071
|
-
| `protobuf` | Export to Protobuf | ✅
|
|
1072
|
-
| `terraform` | Export to terraform resources | ✅
|
|
1073
|
-
| `sql` | Export to SQL DDL | ✅
|
|
1074
|
-
| `sql-query` | Export to SQL Query | ✅
|
|
1075
|
-
| `great-expectations` | Export to Great Expectations Suites in JSON Format | ✅
|
|
1076
|
-
| `bigquery` | Export to BigQuery Schemas | ✅
|
|
1077
|
-
| `go` | Export to Go types | ✅
|
|
1078
|
-
| `pydantic-model` | Export to pydantic models | ✅
|
|
1079
|
-
| `DBML` | Export to a DBML Diagram description | ✅
|
|
1080
|
-
| `spark` | Export to a Spark StructType | ✅
|
|
1081
|
-
| `sqlalchemy` | Export to SQLAlchemy Models | ✅
|
|
1082
|
-
| `data-caterer` | Export to Data Caterer in YAML format | ✅
|
|
1083
|
-
| `dcs` | Export to Data Contract Specification in YAML format | ✅
|
|
1084
|
-
| `markdown` | Export to Markdown | ✅
|
|
1068
|
+
| Type | Description | Status |
|
|
1069
|
+
|----------------------|---------------------------------------------------------|---------|
|
|
1070
|
+
| `html` | Export to HTML | ✅ |
|
|
1071
|
+
| `jsonschema` | Export to JSON Schema | ✅ |
|
|
1072
|
+
| `odcs` | Export to Open Data Contract Standard (ODCS) V3 | ✅ |
|
|
1073
|
+
| `sodacl` | Export to SodaCL quality checks in YAML format | ✅ |
|
|
1074
|
+
| `dbt` | Export to dbt models in YAML format | ✅ |
|
|
1075
|
+
| `dbt-sources` | Export to dbt sources in YAML format | ✅ |
|
|
1076
|
+
| `dbt-staging-sql` | Export to dbt staging SQL models | ✅ |
|
|
1077
|
+
| `rdf` | Export data contract to RDF representation in N3 format | ✅ |
|
|
1078
|
+
| `avro` | Export to AVRO models | ✅ |
|
|
1079
|
+
| `protobuf` | Export to Protobuf | ✅ |
|
|
1080
|
+
| `terraform` | Export to terraform resources | ✅ |
|
|
1081
|
+
| `sql` | Export to SQL DDL | ✅ |
|
|
1082
|
+
| `sql-query` | Export to SQL Query | ✅ |
|
|
1083
|
+
| `great-expectations` | Export to Great Expectations Suites in JSON Format | ✅ |
|
|
1084
|
+
| `bigquery` | Export to BigQuery Schemas | ✅ |
|
|
1085
|
+
| `go` | Export to Go types | ✅ |
|
|
1086
|
+
| `pydantic-model` | Export to pydantic models | ✅ |
|
|
1087
|
+
| `DBML` | Export to a DBML Diagram description | ✅ |
|
|
1088
|
+
| `spark` | Export to a Spark StructType | ✅ |
|
|
1089
|
+
| `sqlalchemy` | Export to SQLAlchemy Models | ✅ |
|
|
1090
|
+
| `data-caterer` | Export to Data Caterer in YAML format | ✅ |
|
|
1091
|
+
| `dcs` | Export to Data Contract Specification in YAML format | ✅ |
|
|
1092
|
+
| `markdown` | Export to Markdown | ✅ |
|
|
1085
1093
|
| `iceberg` | Export to an Iceberg JSON Schema Definition | partial |
|
|
1086
|
-
| `excel` | Export to ODCS Excel Template | ✅
|
|
1087
|
-
| `custom` | Export to Custom format with Jinja | ✅
|
|
1088
|
-
|
|
|
1094
|
+
| `excel` | Export to ODCS Excel Template | ✅ |
|
|
1095
|
+
| `custom` | Export to Custom format with Jinja | ✅ |
|
|
1096
|
+
| `dqx` | Export to DQX in YAML format | ✅ |
|
|
1097
|
+
| Missing something? | Please create an issue on GitHub | TBD |
|
|
1089
1098
|
|
|
1090
1099
|
#### SQL
|
|
1091
1100
|
|
|
@@ -161,6 +161,14 @@ if not run.has_passed():
|
|
|
161
161
|
|
|
162
162
|
Choose the most appropriate installation method for your needs:
|
|
163
163
|
|
|
164
|
+
### uv
|
|
165
|
+
|
|
166
|
+
If you have [uv](https://docs.astral.sh/uv/) installed, you can run datacontract-cli directly without installing:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
uv run --with 'datacontract-cli[all]' datacontract --version
|
|
170
|
+
```
|
|
171
|
+
|
|
164
172
|
### pip
|
|
165
173
|
Python 3.10, 3.11, and 3.12 are supported. We recommend to use Python 3.11.
|
|
166
174
|
|
|
@@ -915,7 +923,7 @@ models:
|
|
|
915
923
|
│ terraform|avro-idl|sql|sql-query|mer │
|
|
916
924
|
│ maid|html|go|bigquery|dbml|spark|sql │
|
|
917
925
|
│ alchemy|data-caterer|dcs|markdown|ic │
|
|
918
|
-
│ eberg|custom|excel] │
|
|
926
|
+
│ eberg|custom|excel|dqx] │
|
|
919
927
|
│ --output PATH Specify the file path where the │
|
|
920
928
|
│ exported data will be saved. If no │
|
|
921
929
|
│ path is provided, the output will be │
|
|
@@ -961,35 +969,36 @@ datacontract export --format html --output datacontract.html
|
|
|
961
969
|
|
|
962
970
|
Available export options:
|
|
963
971
|
|
|
964
|
-
| Type | Description | Status
|
|
965
|
-
|
|
966
|
-
| `html` | Export to HTML | ✅
|
|
967
|
-
| `jsonschema` | Export to JSON Schema | ✅
|
|
968
|
-
| `odcs` | Export to Open Data Contract Standard (ODCS) V3 | ✅
|
|
969
|
-
| `sodacl` | Export to SodaCL quality checks in YAML format | ✅
|
|
970
|
-
| `dbt` | Export to dbt models in YAML format | ✅
|
|
971
|
-
| `dbt-sources` | Export to dbt sources in YAML format | ✅
|
|
972
|
-
| `dbt-staging-sql` | Export to dbt staging SQL models | ✅
|
|
973
|
-
| `rdf` | Export data contract to RDF representation in N3 format | ✅
|
|
974
|
-
| `avro` | Export to AVRO models | ✅
|
|
975
|
-
| `protobuf` | Export to Protobuf | ✅
|
|
976
|
-
| `terraform` | Export to terraform resources | ✅
|
|
977
|
-
| `sql` | Export to SQL DDL | ✅
|
|
978
|
-
| `sql-query` | Export to SQL Query | ✅
|
|
979
|
-
| `great-expectations` | Export to Great Expectations Suites in JSON Format | ✅
|
|
980
|
-
| `bigquery` | Export to BigQuery Schemas | ✅
|
|
981
|
-
| `go` | Export to Go types | ✅
|
|
982
|
-
| `pydantic-model` | Export to pydantic models | ✅
|
|
983
|
-
| `DBML` | Export to a DBML Diagram description | ✅
|
|
984
|
-
| `spark` | Export to a Spark StructType | ✅
|
|
985
|
-
| `sqlalchemy` | Export to SQLAlchemy Models | ✅
|
|
986
|
-
| `data-caterer` | Export to Data Caterer in YAML format | ✅
|
|
987
|
-
| `dcs` | Export to Data Contract Specification in YAML format | ✅
|
|
988
|
-
| `markdown` | Export to Markdown | ✅
|
|
972
|
+
| Type | Description | Status |
|
|
973
|
+
|----------------------|---------------------------------------------------------|---------|
|
|
974
|
+
| `html` | Export to HTML | ✅ |
|
|
975
|
+
| `jsonschema` | Export to JSON Schema | ✅ |
|
|
976
|
+
| `odcs` | Export to Open Data Contract Standard (ODCS) V3 | ✅ |
|
|
977
|
+
| `sodacl` | Export to SodaCL quality checks in YAML format | ✅ |
|
|
978
|
+
| `dbt` | Export to dbt models in YAML format | ✅ |
|
|
979
|
+
| `dbt-sources` | Export to dbt sources in YAML format | ✅ |
|
|
980
|
+
| `dbt-staging-sql` | Export to dbt staging SQL models | ✅ |
|
|
981
|
+
| `rdf` | Export data contract to RDF representation in N3 format | ✅ |
|
|
982
|
+
| `avro` | Export to AVRO models | ✅ |
|
|
983
|
+
| `protobuf` | Export to Protobuf | ✅ |
|
|
984
|
+
| `terraform` | Export to terraform resources | ✅ |
|
|
985
|
+
| `sql` | Export to SQL DDL | ✅ |
|
|
986
|
+
| `sql-query` | Export to SQL Query | ✅ |
|
|
987
|
+
| `great-expectations` | Export to Great Expectations Suites in JSON Format | ✅ |
|
|
988
|
+
| `bigquery` | Export to BigQuery Schemas | ✅ |
|
|
989
|
+
| `go` | Export to Go types | ✅ |
|
|
990
|
+
| `pydantic-model` | Export to pydantic models | ✅ |
|
|
991
|
+
| `DBML` | Export to a DBML Diagram description | ✅ |
|
|
992
|
+
| `spark` | Export to a Spark StructType | ✅ |
|
|
993
|
+
| `sqlalchemy` | Export to SQLAlchemy Models | ✅ |
|
|
994
|
+
| `data-caterer` | Export to Data Caterer in YAML format | ✅ |
|
|
995
|
+
| `dcs` | Export to Data Contract Specification in YAML format | ✅ |
|
|
996
|
+
| `markdown` | Export to Markdown | ✅ |
|
|
989
997
|
| `iceberg` | Export to an Iceberg JSON Schema Definition | partial |
|
|
990
|
-
| `excel` | Export to ODCS Excel Template | ✅
|
|
991
|
-
| `custom` | Export to Custom format with Jinja | ✅
|
|
992
|
-
|
|
|
998
|
+
| `excel` | Export to ODCS Excel Template | ✅ |
|
|
999
|
+
| `custom` | Export to Custom format with Jinja | ✅ |
|
|
1000
|
+
| `dqx` | Export to DQX in YAML format | ✅ |
|
|
1001
|
+
| Missing something? | Please create an issue on GitHub | TBD |
|
|
993
1002
|
|
|
994
1003
|
#### SQL
|
|
995
1004
|
|
|
@@ -162,15 +162,22 @@ async def test(
|
|
|
162
162
|
server: Annotated[
|
|
163
163
|
str | None,
|
|
164
164
|
Query(
|
|
165
|
-
examples=["production"],
|
|
166
165
|
description="The server name to test. Optional, if there is only one server.",
|
|
166
|
+
examples=["production"],
|
|
167
|
+
),
|
|
168
|
+
] = None,
|
|
169
|
+
publish_url: Annotated[
|
|
170
|
+
str | None,
|
|
171
|
+
Query(
|
|
172
|
+
description="URL to publish test results. Optional, if you want to publish the test results to a Data Mesh Manager or Data Contract Manager. Example: https://api.datamesh-manager.com/api/test-results",
|
|
173
|
+
examples=["https://api.datamesh-manager.com/api/test-results"],
|
|
167
174
|
),
|
|
168
175
|
] = None,
|
|
169
176
|
) -> Run:
|
|
170
177
|
check_api_key(api_key)
|
|
171
178
|
logging.info("Testing data contract...")
|
|
172
179
|
logging.info(body)
|
|
173
|
-
return DataContract(data_contract_str=body, server=server).test()
|
|
180
|
+
return DataContract(data_contract_str=body, server=server, publish_url=publish_url).test()
|
|
174
181
|
|
|
175
182
|
|
|
176
183
|
@app.post(
|
|
@@ -126,8 +126,10 @@ def test(
|
|
|
126
126
|
"servers (default)."
|
|
127
127
|
),
|
|
128
128
|
] = "all",
|
|
129
|
-
publish_test_results: Annotated[
|
|
130
|
-
|
|
129
|
+
publish_test_results: Annotated[
|
|
130
|
+
bool, typer.Option(help="Deprecated. Use publish parameter. Publish the results after the test")
|
|
131
|
+
] = False,
|
|
132
|
+
publish: Annotated[str, typer.Option(help="The url to publish the results after the test.")] = None,
|
|
131
133
|
output: Annotated[
|
|
132
134
|
Path,
|
|
133
135
|
typer.Option(
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import glob
|
|
1
2
|
import json
|
|
2
3
|
import logging
|
|
3
4
|
import os
|
|
4
5
|
import threading
|
|
5
|
-
from typing import List, Optional
|
|
6
|
+
from typing import Any, Callable, Generator, List, Optional
|
|
6
7
|
|
|
7
8
|
import fastjsonschema
|
|
8
9
|
from fastjsonschema import JsonSchemaValueException
|
|
@@ -85,7 +86,7 @@ def process_exceptions(run, exceptions: List[DataContractException]):
|
|
|
85
86
|
|
|
86
87
|
|
|
87
88
|
def validate_json_stream(
|
|
88
|
-
schema: dict, model_name: str, validate:
|
|
89
|
+
schema: dict, model_name: str, validate: Callable, json_stream: Generator[Any, Any, None]
|
|
89
90
|
) -> List[DataContractException]:
|
|
90
91
|
logging.info(f"Validating JSON stream for model: '{model_name}'.")
|
|
91
92
|
exceptions: List[DataContractException] = []
|
|
@@ -99,7 +100,7 @@ def validate_json_stream(
|
|
|
99
100
|
DataContractException(
|
|
100
101
|
type="schema",
|
|
101
102
|
name="Check that JSON has valid schema",
|
|
102
|
-
result=
|
|
103
|
+
result=ResultEnum.failed,
|
|
103
104
|
reason=f"{f'#{primary_key_value}: ' if primary_key_value is not None else ''}{e.message}",
|
|
104
105
|
model=model_name,
|
|
105
106
|
engine="jsonschema",
|
|
@@ -170,24 +171,33 @@ def process_local_file(run, server, schema, model_name, validate):
|
|
|
170
171
|
if "{model}" in path:
|
|
171
172
|
path = path.format(model=model_name)
|
|
172
173
|
|
|
174
|
+
all_files = []
|
|
173
175
|
if os.path.isdir(path):
|
|
174
|
-
|
|
176
|
+
# Fetch all JSONs in the directory
|
|
177
|
+
for root, _, files in os.walk(path):
|
|
178
|
+
for file in files:
|
|
179
|
+
if file.endswith(".json"):
|
|
180
|
+
all_files.append(os.path.join(root, file))
|
|
175
181
|
else:
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
182
|
+
# Use glob to fetch all JSONs
|
|
183
|
+
for file_path in glob.glob(path, recursive=True):
|
|
184
|
+
if os.path.isfile(file_path):
|
|
185
|
+
if file_path.endswith(".json"):
|
|
186
|
+
all_files.append(file_path)
|
|
179
187
|
|
|
188
|
+
if not all_files:
|
|
189
|
+
raise DataContractException(
|
|
190
|
+
type="schema",
|
|
191
|
+
name="Check that JSON has valid schema",
|
|
192
|
+
result=ResultEnum.warning,
|
|
193
|
+
reason=f"No files found in '{path}'.",
|
|
194
|
+
engine="datacontract",
|
|
195
|
+
)
|
|
180
196
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
file_path = os.path.join(path, filename)
|
|
186
|
-
with open(file_path, "r") as file:
|
|
187
|
-
if not process_json_file(run, model_name, validate, file, server.delimiter):
|
|
188
|
-
success = False
|
|
189
|
-
break
|
|
190
|
-
return success
|
|
197
|
+
for file in all_files:
|
|
198
|
+
logging.info(f"Processing file: {file}")
|
|
199
|
+
with open(file, "r") as f:
|
|
200
|
+
process_json_file(run, schema, model_name, validate, f, server.delimiter)
|
|
191
201
|
|
|
192
202
|
|
|
193
203
|
def process_s3_file(run, server, schema, model_name, validate):
|
|
@@ -209,7 +219,7 @@ def process_s3_file(run, server, schema, model_name, validate):
|
|
|
209
219
|
raise DataContractException(
|
|
210
220
|
type="schema",
|
|
211
221
|
name="Check that JSON has valid schema",
|
|
212
|
-
result=
|
|
222
|
+
result=ResultEnum.warning,
|
|
213
223
|
reason=f"Cannot find any file in {s3_location}",
|
|
214
224
|
engine="datacontract",
|
|
215
225
|
)
|
|
@@ -230,7 +240,7 @@ def check_jsonschema(run: Run, data_contract: DataContractSpecification, server:
|
|
|
230
240
|
Check(
|
|
231
241
|
type="schema",
|
|
232
242
|
name="Check that JSON has valid schema",
|
|
233
|
-
result=
|
|
243
|
+
result=ResultEnum.warning,
|
|
234
244
|
reason="Server format is not 'json'. Skip validating jsonschema.",
|
|
235
245
|
engine="jsonschema",
|
|
236
246
|
)
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
from typing import Any, Dict, List, Union
|
|
2
|
+
|
|
3
|
+
import yaml
|
|
4
|
+
|
|
5
|
+
from datacontract.export.exporter import Exporter, _check_models_for_export
|
|
6
|
+
from datacontract.model.data_contract_specification import DataContractSpecification, Field, Model, Quality
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DqxKeys:
|
|
10
|
+
CHECK = "check"
|
|
11
|
+
ARGUMENTS = "arguments"
|
|
12
|
+
SPECIFICATION = "specification"
|
|
13
|
+
COL_NAME = "column"
|
|
14
|
+
COL_NAMES = "for_each_column"
|
|
15
|
+
COLUMNS = "columns"
|
|
16
|
+
FUNCTION = "function"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class DqxExporter(Exporter):
|
|
20
|
+
"""Exporter implementation for converting data contracts to DQX YAML file."""
|
|
21
|
+
|
|
22
|
+
def export(
|
|
23
|
+
self,
|
|
24
|
+
data_contract: DataContractSpecification,
|
|
25
|
+
model: Model,
|
|
26
|
+
server: str,
|
|
27
|
+
sql_server_type: str,
|
|
28
|
+
export_args: Dict[str, Any],
|
|
29
|
+
) -> str:
|
|
30
|
+
"""Exports a data contract to DQX format."""
|
|
31
|
+
model_name, model_value = _check_models_for_export(data_contract, model, self.export_format)
|
|
32
|
+
return to_dqx_yaml(model_value)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def to_dqx_yaml(model_value: Model) -> str:
|
|
36
|
+
"""
|
|
37
|
+
Converts the data contract's quality checks to DQX YAML format.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
model_value (Model): The data contract to convert.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
str: YAML representation of the data contract's quality checks.
|
|
44
|
+
"""
|
|
45
|
+
extracted_rules = extract_quality_rules(model_value)
|
|
46
|
+
return yaml.dump(extracted_rules, sort_keys=False, allow_unicode=True, default_flow_style=False)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def process_quality_rule(rule: Quality, column_name: str) -> Dict[str, Any]:
|
|
50
|
+
"""
|
|
51
|
+
Processes a single quality rule by injecting the column path into its arguments if absent.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
rule (Quality): The quality rule to process.
|
|
55
|
+
column_name (str): The full path to the current column.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
dict: The processed quality rule specification.
|
|
59
|
+
"""
|
|
60
|
+
rule_data = rule.model_extra
|
|
61
|
+
specification = rule_data[DqxKeys.SPECIFICATION]
|
|
62
|
+
check = specification[DqxKeys.CHECK]
|
|
63
|
+
|
|
64
|
+
arguments = check.setdefault(DqxKeys.ARGUMENTS, {})
|
|
65
|
+
|
|
66
|
+
if DqxKeys.COL_NAME not in arguments and DqxKeys.COL_NAMES not in arguments and DqxKeys.COLUMNS not in arguments:
|
|
67
|
+
if check[DqxKeys.FUNCTION] not in ("is_unique", "foreign_key"):
|
|
68
|
+
arguments[DqxKeys.COL_NAME] = column_name
|
|
69
|
+
else:
|
|
70
|
+
arguments[DqxKeys.COLUMNS] = [column_name]
|
|
71
|
+
|
|
72
|
+
return specification
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def extract_quality_rules(data: Union[Model, Field, Quality], column_path: str = "") -> List[Dict[str, Any]]:
|
|
76
|
+
"""
|
|
77
|
+
Recursively extracts all quality rules from a data contract structure.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
data (Union[Model, Field, Quality]): The data contract model, field, or quality rule.
|
|
81
|
+
column_path (str, optional): The current path in the schema hierarchy. Defaults to "".
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
List[Dict[str, Any]]: A list of quality rule specifications.
|
|
85
|
+
"""
|
|
86
|
+
quality_rules = []
|
|
87
|
+
|
|
88
|
+
if isinstance(data, Quality):
|
|
89
|
+
return [process_quality_rule(data, column_path)]
|
|
90
|
+
|
|
91
|
+
if isinstance(data, (Model, Field)):
|
|
92
|
+
for key, field in data.fields.items():
|
|
93
|
+
current_path = build_column_path(column_path, key)
|
|
94
|
+
|
|
95
|
+
if field.fields:
|
|
96
|
+
# Field is a struct-like object, recurse deeper
|
|
97
|
+
quality_rules.extend(extract_quality_rules(field, current_path))
|
|
98
|
+
else:
|
|
99
|
+
# Process quality rules at leaf fields
|
|
100
|
+
for rule in field.quality:
|
|
101
|
+
quality_rules.append(process_quality_rule(rule, current_path))
|
|
102
|
+
|
|
103
|
+
# Process any quality rules attached directly to this level
|
|
104
|
+
for rule in data.quality:
|
|
105
|
+
quality_rules.append(process_quality_rule(rule, column_path))
|
|
106
|
+
|
|
107
|
+
return quality_rules
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def build_column_path(current_path: str, key: str) -> str:
|
|
111
|
+
"""
|
|
112
|
+
Builds the full column path by concatenating parent path with current key.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
current_path (str): The current path prefix.
|
|
116
|
+
key (str): The current field's key.
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
str: The full path.
|
|
120
|
+
"""
|
|
121
|
+
return f"{current_path}.{key}" if current_path else key
|
{datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/exporter_factory.py
RENAMED
|
@@ -197,6 +197,12 @@ exporter_factory.register_lazy_exporter(
|
|
|
197
197
|
class_name="MarkdownExporter",
|
|
198
198
|
)
|
|
199
199
|
|
|
200
|
+
exporter_factory.register_lazy_exporter(
|
|
201
|
+
name=ExportFormat.dqx,
|
|
202
|
+
module_path="datacontract.export.dqx_converter",
|
|
203
|
+
class_name="DqxExporter",
|
|
204
|
+
)
|
|
205
|
+
|
|
200
206
|
exporter_factory.register_lazy_exporter(
|
|
201
207
|
name=ExportFormat.iceberg, module_path="datacontract.export.iceberg_converter", class_name="IcebergExporter"
|
|
202
208
|
)
|
{datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/mermaid_exporter.py
RENAMED
|
@@ -27,31 +27,33 @@ def dcs_to_mermaid(data_contract_spec: DataContractSpecification) -> str | None:
|
|
|
27
27
|
mmd_references = []
|
|
28
28
|
|
|
29
29
|
for model_name, model in data_contract_spec.models.items():
|
|
30
|
+
clean_model = _sanitize_name(model_name)
|
|
30
31
|
entity_block = ""
|
|
31
32
|
|
|
32
33
|
for field_name, field in model.fields.items():
|
|
33
34
|
clean_name = _sanitize_name(field_name)
|
|
34
|
-
|
|
35
|
+
field_type = field.type or "unknown"
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if field.references:
|
|
39
|
-
indicators += "⌘"
|
|
37
|
+
is_pk = bool(field.primaryKey or (field.unique and field.required))
|
|
38
|
+
is_fk = bool(field.references)
|
|
40
39
|
|
|
41
|
-
field_type = field.
|
|
42
|
-
entity_block += f"\t{clean_name}{indicators} {field_type}\n"
|
|
40
|
+
entity_block += _field_line(clean_name, field_type, pk=is_pk, uk=bool(field.unique), fk=is_fk)
|
|
43
41
|
|
|
44
42
|
if field.references:
|
|
45
|
-
|
|
43
|
+
references = field.references.replace(".", "·")
|
|
44
|
+
parts = references.split("·")
|
|
45
|
+
referenced_model = _sanitize_name(parts[0]) if len(parts) > 0 else ""
|
|
46
|
+
referenced_field = _sanitize_name(parts[1]) if len(parts) > 1 else ""
|
|
46
47
|
if referenced_model:
|
|
47
|
-
|
|
48
|
+
label = referenced_field or clean_name
|
|
49
|
+
mmd_references.append(f'"**{referenced_model}**" ||--o{{ "**{clean_model}**" : {label}')
|
|
48
50
|
|
|
49
|
-
mmd_entity += f'\t"**{
|
|
51
|
+
mmd_entity += f'\t"**{clean_model}**" {{\n{entity_block}}}\n'
|
|
50
52
|
|
|
51
53
|
if mmd_references:
|
|
52
54
|
mmd_entity += "\n" + "\n".join(mmd_references)
|
|
53
55
|
|
|
54
|
-
return
|
|
56
|
+
return mmd_entity + "\n"
|
|
55
57
|
|
|
56
58
|
except Exception as e:
|
|
57
59
|
print(f"Error generating DCS mermaid diagram: {e}")
|
|
@@ -95,3 +97,14 @@ def odcs_to_mermaid(data_contract_spec: OpenDataContractStandard) -> str | None:
|
|
|
95
97
|
|
|
96
98
|
def _sanitize_name(name: str) -> str:
|
|
97
99
|
return name.replace("#", "Nb").replace(" ", "_").replace("/", "by")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _field_line(name: str, field_type: str, pk: bool = False, uk: bool = False, fk: bool = False) -> str:
|
|
103
|
+
indicators = ""
|
|
104
|
+
if pk:
|
|
105
|
+
indicators += "🔑"
|
|
106
|
+
if uk:
|
|
107
|
+
indicators += "🔒"
|
|
108
|
+
if fk:
|
|
109
|
+
indicators += "⌘"
|
|
110
|
+
return f"\t{name}{indicators} {field_type}\n"
|
{datacontract_cli-0.10.34 → datacontract_cli-0.10.35}/datacontract/export/spark_converter.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
1
3
|
from pyspark.sql import types
|
|
2
4
|
|
|
3
5
|
from datacontract.export.exporter import Exporter
|
|
@@ -104,7 +106,8 @@ def to_struct_field(field: Field, field_name: str) -> types.StructField:
|
|
|
104
106
|
types.StructField: The corresponding Spark StructField.
|
|
105
107
|
"""
|
|
106
108
|
data_type = to_spark_data_type(field)
|
|
107
|
-
|
|
109
|
+
metadata = to_spark_metadata(field)
|
|
110
|
+
return types.StructField(name=field_name, dataType=data_type, nullable=not field.required, metadata=metadata)
|
|
108
111
|
|
|
109
112
|
|
|
110
113
|
def to_spark_data_type(field: Field) -> types.DataType:
|
|
@@ -152,7 +155,25 @@ def to_spark_data_type(field: Field) -> types.DataType:
|
|
|
152
155
|
return types.DateType()
|
|
153
156
|
if field_type == "bytes":
|
|
154
157
|
return types.BinaryType()
|
|
155
|
-
return types.StringType()
|
|
158
|
+
return types.StringType() # default if no condition is met
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def to_spark_metadata(field: Field) -> dict[str, str]:
|
|
162
|
+
"""
|
|
163
|
+
Convert a field to a Spark metadata dictonary.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
field (Field): The field to convert.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
dict: dictionary that can be supplied to Spark as metadata for a StructField
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
metadata = {}
|
|
173
|
+
if field.description:
|
|
174
|
+
metadata["comment"] = field.description
|
|
175
|
+
|
|
176
|
+
return metadata
|
|
156
177
|
|
|
157
178
|
|
|
158
179
|
def print_schema(dtype: types.DataType) -> str:
|
|
@@ -192,7 +213,11 @@ def print_schema(dtype: types.DataType) -> str:
|
|
|
192
213
|
name = f'"{column.name}"'
|
|
193
214
|
data_type = indent(print_schema(column.dataType), 1)
|
|
194
215
|
nullable = indent(f"{column.nullable}", 1)
|
|
195
|
-
|
|
216
|
+
if column.metadata:
|
|
217
|
+
metadata = indent(f"{json.dumps(column.metadata)}", 1)
|
|
218
|
+
return f"StructField({name},\n{data_type},\n{nullable},\n{metadata}\n)"
|
|
219
|
+
else:
|
|
220
|
+
return f"StructField({name},\n{data_type},\n{nullable}\n)"
|
|
196
221
|
|
|
197
222
|
def format_struct_type(struct_type: types.StructType) -> str:
|
|
198
223
|
"""
|