pycharter 0.0.20__tar.gz → 0.0.23__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.20 → pycharter-0.0.23}/MANIFEST.in +2 -0
- {pycharter-0.0.20/pycharter.egg-info → pycharter-0.0.23}/PKG-INFO +289 -62
- {pycharter-0.0.20 → pycharter-0.0.23}/README.md +282 -61
- {pycharter-0.0.20 → pycharter-0.0.23}/api/dependencies/__init__.py +2 -1
- {pycharter-0.0.20 → pycharter-0.0.23}/api/dependencies/database.py +71 -5
- {pycharter-0.0.20 → pycharter-0.0.23}/api/main.py +47 -8
- {pycharter-0.0.20 → pycharter-0.0.23}/api/models/contracts.py +6 -4
- {pycharter-0.0.20 → pycharter-0.0.23}/api/models/metadata.py +11 -7
- {pycharter-0.0.20 → pycharter-0.0.23}/api/models/schemas.py +16 -10
- {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/contracts.py +498 -226
- {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/metadata.py +52 -211
- {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/schemas.py +1 -1
- {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/settings.py +88 -1
- {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/templates.py +43 -24
- pycharter-0.0.23/api/utils.py +224 -0
- pycharter-0.0.23/pycharter/__init__.py +211 -0
- pycharter-0.0.23/pycharter/data/templates/etl/README.md +91 -0
- pycharter-0.0.23/pycharter/data/templates/etl/extract_cloud_azure.yaml +23 -0
- pycharter-0.0.23/pycharter/data/templates/etl/extract_cloud_gcs.yaml +22 -0
- pycharter-0.0.23/pycharter/data/templates/etl/extract_cloud_s3.yaml +24 -0
- pycharter-0.0.23/pycharter/data/templates/etl/extract_database.yaml +28 -0
- pycharter-0.0.23/pycharter/data/templates/etl/extract_database_ssh.yaml +27 -0
- pycharter-0.0.23/pycharter/data/templates/etl/extract_file_csv.yaml +17 -0
- pycharter-0.0.23/pycharter/data/templates/etl/extract_file_glob.yaml +17 -0
- pycharter-0.0.23/pycharter/data/templates/etl/extract_file_json.yaml +14 -0
- pycharter-0.0.23/pycharter/data/templates/etl/extract_file_parquet.yaml +13 -0
- pycharter-0.0.23/pycharter/data/templates/etl/extract_http_paginated.yaml +75 -0
- pycharter-0.0.23/pycharter/data/templates/etl/extract_http_path_params.yaml +45 -0
- pycharter-0.0.23/pycharter/data/templates/etl/extract_http_simple.yaml +52 -0
- pycharter-0.0.23/pycharter/data/templates/etl/load_insert.yaml +17 -0
- pycharter-0.0.23/pycharter/data/templates/etl/load_postgresql.yaml +17 -0
- pycharter-0.0.23/pycharter/data/templates/etl/load_sqlite.yaml +16 -0
- pycharter-0.0.23/pycharter/data/templates/etl/load_truncate_and_load.yaml +18 -0
- pycharter-0.0.23/pycharter/data/templates/etl/load_upsert.yaml +28 -0
- pycharter-0.0.23/pycharter/data/templates/etl/load_with_dlq.yaml +24 -0
- pycharter-0.0.23/pycharter/data/templates/etl/load_with_ssh_tunnel.yaml +28 -0
- pycharter-0.0.23/pycharter/data/templates/etl/pipeline_http_to_db.yaml +38 -0
- pycharter-0.0.23/pycharter/data/templates/etl/transform_combined.yaml +38 -0
- pycharter-0.0.23/pycharter/data/templates/etl/transform_custom_function.yaml +18 -0
- pycharter-0.0.23/pycharter/data/templates/etl/transform_jsonata.yaml +20 -0
- pycharter-0.0.23/pycharter/data/templates/etl/transform_simple.yaml +41 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/base.py +1 -2
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/extraction.py +47 -262
- pycharter-0.0.23/pycharter/etl_generator/extractors/__init__.py +26 -0
- pycharter-0.0.23/pycharter/etl_generator/extractors/base.py +70 -0
- pycharter-0.0.23/pycharter/etl_generator/extractors/cloud_storage.py +454 -0
- pycharter-0.0.23/pycharter/etl_generator/extractors/database.py +151 -0
- pycharter-0.0.23/pycharter/etl_generator/extractors/factory.py +141 -0
- pycharter-0.0.23/pycharter/etl_generator/extractors/file.py +418 -0
- pycharter-0.0.23/pycharter/etl_generator/extractors/http.py +816 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/orchestrator.py +463 -487
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/metadata_store/postgres.py +16 -191
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/metadata_store/sqlite.py +12 -41
- {pycharter-0.0.20 → pycharter-0.0.23/pycharter.egg-info}/PKG-INFO +289 -62
- pycharter-0.0.23/pycharter.egg-info/SOURCES.txt +516 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter.egg-info/requires.txt +6 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pyproject.toml +14 -3
- pycharter-0.0.23/tests/test_extractors.py +279 -0
- pycharter-0.0.23/ui/static/404/index.html +1 -0
- pycharter-0.0.23/ui/static/404.html +1 -0
- pycharter-0.0.23/ui/static/__next.__PAGE__.txt +10 -0
- pycharter-0.0.23/ui/static/__next._full.txt +30 -0
- pycharter-0.0.23/ui/static/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/_next/static/chunks/13d4a0fbd74c1ee4.js +1 -0
- pycharter-0.0.23/ui/static/_next/static/chunks/26dfc590f7714c03.js +1 -0
- pycharter-0.0.23/ui/static/_next/static/chunks/2edb43b48432ac04.js +441 -0
- pycharter-0.0.23/ui/static/_next/static/chunks/34d289e6db2ef551.js +1 -0
- pycharter-0.0.23/ui/static/_next/static/chunks/99508d9d5869cc27.js +1 -0
- pycharter-0.0.23/ui/static/_next/static/chunks/b313c35a6ba76574.js +1 -0
- pycharter-0.0.23/ui/static/_next/static/chunks/d2363397e1b2bcab.css +1 -0
- pycharter-0.0.23/ui/static/_next/static/chunks/f7d1a90dd75d2572.js +1 -0
- pycharter-0.0.23/ui/static/_not-found/__next._full.txt +17 -0
- pycharter-0.0.23/ui/static/_not-found/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/_not-found/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/_not-found/__next._not-found.__PAGE__.txt +5 -0
- pycharter-0.0.23/ui/static/_not-found/__next._not-found.txt +4 -0
- pycharter-0.0.23/ui/static/_not-found/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/_not-found/index.html +1 -0
- pycharter-0.0.23/ui/static/_not-found/index.txt +17 -0
- pycharter-0.0.23/ui/static/contracts/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/contracts/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/contracts/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/contracts/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/contracts/__next.contracts.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/contracts/__next.contracts.txt +4 -0
- pycharter-0.0.23/ui/static/contracts/index.html +1 -0
- pycharter-0.0.23/ui/static/contracts/index.txt +21 -0
- pycharter-0.0.23/ui/static/documentation/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/documentation/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/documentation/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/documentation/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/documentation/__next.documentation.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/documentation/__next.documentation.txt +4 -0
- pycharter-0.0.23/ui/static/documentation/index.html +93 -0
- pycharter-0.0.23/ui/static/documentation/index.txt +21 -0
- pycharter-0.0.23/ui/static/index.html +1 -0
- pycharter-0.0.23/ui/static/index.txt +30 -0
- pycharter-0.0.23/ui/static/metadata/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/metadata/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/metadata/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/metadata/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/metadata/__next.metadata.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/metadata/__next.metadata.txt +4 -0
- pycharter-0.0.23/ui/static/metadata/index.html +1 -0
- pycharter-0.0.23/ui/static/metadata/index.txt +21 -0
- pycharter-0.0.23/ui/static/quality/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/quality/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/quality/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/quality/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/quality/__next.quality.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/quality/__next.quality.txt +4 -0
- pycharter-0.0.23/ui/static/quality/index.html +2 -0
- pycharter-0.0.23/ui/static/quality/index.txt +21 -0
- pycharter-0.0.23/ui/static/rules/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/rules/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/rules/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/rules/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/rules/__next.rules.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/rules/__next.rules.txt +4 -0
- pycharter-0.0.23/ui/static/rules/index.html +1 -0
- pycharter-0.0.23/ui/static/rules/index.txt +21 -0
- pycharter-0.0.23/ui/static/schemas/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/schemas/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/schemas/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/schemas/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/schemas/__next.schemas.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/schemas/__next.schemas.txt +4 -0
- pycharter-0.0.23/ui/static/schemas/index.html +1 -0
- pycharter-0.0.23/ui/static/schemas/index.txt +21 -0
- pycharter-0.0.23/ui/static/settings/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/settings/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/settings/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/settings/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/settings/__next.settings.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/settings/__next.settings.txt +4 -0
- pycharter-0.0.23/ui/static/settings/index.html +1 -0
- pycharter-0.0.23/ui/static/settings/index.txt +21 -0
- pycharter-0.0.23/ui/static/static/.gitkeep +0 -0
- pycharter-0.0.23/ui/static/static/404/index.html +1 -0
- pycharter-0.0.23/ui/static/static/404.html +1 -0
- pycharter-0.0.23/ui/static/static/__next.__PAGE__.txt +10 -0
- pycharter-0.0.23/ui/static/static/__next._full.txt +30 -0
- pycharter-0.0.23/ui/static/static/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/static/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/static/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/static/_next/static/0rYA78L88aUyD2Uh38hhX/_buildManifest.js +11 -0
- pycharter-0.0.23/ui/static/static/_next/static/0rYA78L88aUyD2Uh38hhX/_ssgManifest.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/13d4a0fbd74c1ee4.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/222442f6da32302a.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/247eb132b7f7b574.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/297d55555b71baba.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/2ab439ce003cd691.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/2edb43b48432ac04.js +441 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/414e77373f8ff61c.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/49ca65abd26ae49e.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/652ad0aa26265c47.js +2 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/9667e7a3d359eb39.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/9c23f44fff36548a.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/a6dad97d9634a72d.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/b32a0963684b9933.js +4 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/c4fa4f4114b7c352.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/c69f6cba366bd988.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/d2363397e1b2bcab.css +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/db913959c675cea6.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/f061a4be97bfc3b3.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/f2e7afeab1178138.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/f7d1a90dd75d2572.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/ff1a16fafef87110.js +1 -0
- pycharter-0.0.23/ui/static/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +3 -0
- pycharter-0.0.23/ui/static/static/_not-found/__next._full.txt +17 -0
- pycharter-0.0.23/ui/static/static/_not-found/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/static/_not-found/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/static/_not-found/__next._not-found.__PAGE__.txt +5 -0
- pycharter-0.0.23/ui/static/static/_not-found/__next._not-found.txt +4 -0
- pycharter-0.0.23/ui/static/static/_not-found/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/static/_not-found/index.html +1 -0
- pycharter-0.0.23/ui/static/static/_not-found/index.txt +17 -0
- pycharter-0.0.23/ui/static/static/contracts/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/static/contracts/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/static/contracts/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/static/contracts/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/static/contracts/__next.contracts.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/static/contracts/__next.contracts.txt +4 -0
- pycharter-0.0.23/ui/static/static/contracts/index.html +1 -0
- pycharter-0.0.23/ui/static/static/contracts/index.txt +21 -0
- pycharter-0.0.23/ui/static/static/documentation/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/static/documentation/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/static/documentation/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/static/documentation/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/static/documentation/__next.documentation.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/static/documentation/__next.documentation.txt +4 -0
- pycharter-0.0.23/ui/static/static/documentation/index.html +93 -0
- pycharter-0.0.23/ui/static/static/documentation/index.txt +21 -0
- pycharter-0.0.23/ui/static/static/index.html +1 -0
- pycharter-0.0.23/ui/static/static/index.txt +30 -0
- pycharter-0.0.23/ui/static/static/metadata/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/static/metadata/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/static/metadata/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/static/metadata/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/static/metadata/__next.metadata.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/static/metadata/__next.metadata.txt +4 -0
- pycharter-0.0.23/ui/static/static/metadata/index.html +1 -0
- pycharter-0.0.23/ui/static/static/metadata/index.txt +21 -0
- pycharter-0.0.23/ui/static/static/quality/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/static/quality/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/static/quality/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/static/quality/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/static/quality/__next.quality.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/static/quality/__next.quality.txt +4 -0
- pycharter-0.0.23/ui/static/static/quality/index.html +2 -0
- pycharter-0.0.23/ui/static/static/quality/index.txt +21 -0
- pycharter-0.0.23/ui/static/static/rules/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/static/rules/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/static/rules/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/static/rules/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/static/rules/__next.rules.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/static/rules/__next.rules.txt +4 -0
- pycharter-0.0.23/ui/static/static/rules/index.html +1 -0
- pycharter-0.0.23/ui/static/static/rules/index.txt +21 -0
- pycharter-0.0.23/ui/static/static/schemas/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/static/schemas/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/static/schemas/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/static/schemas/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/static/schemas/__next.schemas.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/static/schemas/__next.schemas.txt +4 -0
- pycharter-0.0.23/ui/static/static/schemas/index.html +1 -0
- pycharter-0.0.23/ui/static/static/schemas/index.txt +21 -0
- pycharter-0.0.23/ui/static/static/settings/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/static/settings/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/static/settings/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/static/settings/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/static/settings/__next.settings.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/static/settings/__next.settings.txt +4 -0
- pycharter-0.0.23/ui/static/static/settings/index.html +1 -0
- pycharter-0.0.23/ui/static/static/settings/index.txt +21 -0
- pycharter-0.0.23/ui/static/static/static/.gitkeep +0 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/222442f6da32302a.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/247eb132b7f7b574.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/297d55555b71baba.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/2ab439ce003cd691.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/414e77373f8ff61c.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/49ca65abd26ae49e.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/5e04d10c4a7b58a3.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/652ad0aa26265c47.js +2 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/75d88a058d8ffaa6.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/8c89634cf6bad76f.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/9667e7a3d359eb39.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/9c23f44fff36548a.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/a6dad97d9634a72d.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/b32a0963684b9933.js +4 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/c69f6cba366bd988.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/db913959c675cea6.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/f061a4be97bfc3b3.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/f2e7afeab1178138.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/ff1a16fafef87110.js +1 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +3 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_buildManifest.js +11 -0
- pycharter-0.0.23/ui/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_ssgManifest.js +1 -0
- pycharter-0.0.23/ui/static/static/validation/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/static/validation/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/static/validation/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/static/validation/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/static/validation/__next.validation.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/static/validation/__next.validation.txt +4 -0
- pycharter-0.0.23/ui/static/static/validation/index.html +1 -0
- pycharter-0.0.23/ui/static/static/validation/index.txt +21 -0
- pycharter-0.0.23/ui/static/validation/__next._full.txt +21 -0
- pycharter-0.0.23/ui/static/validation/__next._head.txt +7 -0
- pycharter-0.0.23/ui/static/validation/__next._index.txt +9 -0
- pycharter-0.0.23/ui/static/validation/__next._tree.txt +2 -0
- pycharter-0.0.23/ui/static/validation/__next.validation.__PAGE__.txt +9 -0
- pycharter-0.0.23/ui/static/validation/__next.validation.txt +4 -0
- pycharter-0.0.23/ui/static/validation/index.html +1 -0
- pycharter-0.0.23/ui/static/validation/index.txt +21 -0
- pycharter-0.0.20/pycharter/__init__.py +0 -155
- pycharter-0.0.20/pycharter.egg-info/SOURCES.txt +0 -264
- {pycharter-0.0.20 → pycharter-0.0.23}/LICENSE +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/api/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/api/dependencies/store.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/api/models/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/api/models/metadata_entities.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/api/models/quality.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/api/models/validation.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/quality.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/validation.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/validation_jobs.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/cli.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/config.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/contract_builder/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/contract_builder/builder.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/contract_parser/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/contract_parser/parser.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/data/__init__.py +0 -0
- {pycharter-0.0.20/pycharter/data/templates → pycharter-0.0.23/pycharter/data/templates/contract}/template_coercion_rules.yaml +0 -0
- {pycharter-0.0.20/pycharter/data/templates → pycharter-0.0.23/pycharter/data/templates/contract}/template_contract.yaml +0 -0
- {pycharter-0.0.20/pycharter/data/templates → pycharter-0.0.23/pycharter/data/templates/contract}/template_metadata.yaml +0 -0
- {pycharter-0.0.20/pycharter/data/templates → pycharter-0.0.23/pycharter/data/templates/contract}/template_schema.yaml +0 -0
- {pycharter-0.0.20/pycharter/data/templates → pycharter-0.0.23/pycharter/data/templates/contract}/template_validation_rules.yaml +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/cli.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/README +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/env.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/script.py.mako +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20250115120000_add_tier2_tier3_entities.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20251209163657_799b73fe9f6c_initial_schema.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20251209164144_ae0efda02aa1_initial_schema.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20251217160146_f9995dc0f4b3_add_quality_tables.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20251217164915_8b08d78068e3_add_data_version_tracking.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20260110083000_a1b2c3d4e5f6_add_dead_letter_queue_table.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20260120000000_add_name_title_validation_constraints.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20260121000000_remove_artifact_versions_from_data_contracts.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20260122000000_change_artifact_unique_constraints_to_title_version.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/api_endpoint.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/coercion_rule.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/compliance_framework.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/data_contract.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/data_dependency.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/data_feed.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/dlq.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/domain.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/environment.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/metadata_record.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/owner.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/quality_metric.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/quality_violation.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/schema.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/storage_location.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/system.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/tag.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/validation_rule.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/schemas/.ipynb_checkpoints/data_contract-checkpoint.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/schemas/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/schemas/data_contract.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/checkpoint.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/config_generator.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/database.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/dlq.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/factory.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/progress.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/integrations/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/integrations/kafka.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/integrations/streaming.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/json_schema_converter/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/json_schema_converter/converter.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/json_schema_converter/reverse_converter.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/metadata_store/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/metadata_store/client.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/metadata_store/in_memory.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/metadata_store/mongodb.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/metadata_store/redis.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/py.typed +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/pydantic_generator/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/pydantic_generator/converter.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/pydantic_generator/generator.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/quality/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/quality/check.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/quality/cli.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/quality/metrics.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/quality/models.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/quality/profiling.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/quality/violations.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/runtime_validator/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/runtime_validator/decorators.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/runtime_validator/utils.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/runtime_validator/validator.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/runtime_validator/validator_core.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/runtime_validator/wrappers.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/coercions/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/coercions/builtin.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/json_schema_support.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/json_schema_validator.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/name_validator.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/schema_parser.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/schema_resolver.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/validations/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/validations/builtin.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/utils/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/utils/value_injector.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/utils/version.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter.egg-info/dependency_links.txt +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter.egg-info/entry_points.txt +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/pycharter.egg-info/top_level.txt +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/setup.cfg +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/setup.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_contract_builder.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_contract_parser.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_integration.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_json_schema_compliance.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_json_schema_converter.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_metadata_stores.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_pydantic_generator.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_refs_and_definitions.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_runtime_validator.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_schema_parser.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_value_injector.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_x_validators.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/build.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/dev.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/server.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/.gitkeep +0 -0
- {pycharter-0.0.20/ui/static/_next/static/tNTkVW6puVXC4bAm4WrHl → pycharter-0.0.23/ui/static/_next/static/2gKjNv6YvE6BcIdFthBLs}/_buildManifest.js +0 -0
- {pycharter-0.0.20/ui/static/_next/static/tNTkVW6puVXC4bAm4WrHl → pycharter-0.0.23/ui/static/_next/static/2gKjNv6YvE6BcIdFthBLs}/_ssgManifest.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/222442f6da32302a.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/247eb132b7f7b574.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/297d55555b71baba.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/2ab439ce003cd691.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/414e77373f8ff61c.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/49ca65abd26ae49e.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/652ad0aa26265c47.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/9667e7a3d359eb39.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/9c23f44fff36548a.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/a6dad97d9634a72d.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/b32a0963684b9933.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/c69f6cba366bd988.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/db913959c675cea6.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/f061a4be97bfc3b3.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/f2e7afeab1178138.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/ff1a16fafef87110.js +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static}/static/_next/static/chunks/5e04d10c4a7b58a3.js +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static}/static/_next/static/chunks/75d88a058d8ffaa6.js +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static}/static/_next/static/chunks/8c89634cf6bad76f.js +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/404/index.html +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/404.html +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/__next.__PAGE__.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/__next._full.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/__next._head.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/__next._index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/__next._tree.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_next/static/chunks/4e310fe5005770a3.css +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_next/static/chunks/5fc14c00a2779dc5.js +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_next/static/chunks/b584574fdc8ab13e.js +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_next/static/chunks/d5989c94d3614b3a.js +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/__next._full.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/__next._head.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/__next._index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/__next._not-found.__PAGE__.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/__next._not-found.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/__next._tree.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/index.html +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/__next._full.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/__next._head.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/__next._index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/__next._tree.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/__next.contracts.__PAGE__.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/__next.contracts.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/index.html +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/__next._full.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/__next._head.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/__next._index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/__next._tree.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/__next.documentation.__PAGE__.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/__next.documentation.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/index.html +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/index.html +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/__next._full.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/__next._head.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/__next._index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/__next._tree.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/__next.metadata.__PAGE__.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/__next.metadata.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/index.html +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/__next._full.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/__next._head.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/__next._index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/__next._tree.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/__next.quality.__PAGE__.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/__next.quality.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/index.html +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/__next._full.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/__next._head.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/__next._index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/__next._tree.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/__next.rules.__PAGE__.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/__next.rules.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/index.html +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/__next._full.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/__next._head.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/__next._index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/__next._tree.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/__next.schemas.__PAGE__.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/__next.schemas.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/index.html +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/__next._full.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/__next._head.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/__next._index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/__next._tree.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/__next.settings.__PAGE__.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/__next.settings.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/index.html +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/__next._full.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/__next._head.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/__next._index.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/__next._tree.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/__next.validation.__PAGE__.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/__next.validation.txt +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/index.html +0 -0
- {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/index.txt +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/worker/__init__.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/worker/cli.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/worker/models.py +0 -0
- {pycharter-0.0.20 → pycharter-0.0.23}/worker/processor.py +0 -0
|
@@ -17,8 +17,10 @@ prune ui/out
|
|
|
17
17
|
prune ui/src
|
|
18
18
|
prune ui/public
|
|
19
19
|
# Exclude source files but NOT static build files
|
|
20
|
+
# Note: ui/static is explicitly included above, so these excludes won't affect it
|
|
20
21
|
recursive-exclude ui/src *.ts *.tsx *.js *.json *.md
|
|
21
22
|
recursive-exclude ui/src *.config.*
|
|
23
|
+
# Exclude other UI files (but not ui/static which is already included)
|
|
22
24
|
recursive-exclude ui *.ts *.tsx *.json *.md
|
|
23
25
|
recursive-exclude ui *.config.*
|
|
24
26
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycharter
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.23
|
|
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
|
|
@@ -25,6 +25,7 @@ Requires-Dist: numpy>=1.24.0
|
|
|
25
25
|
Requires-Dist: pyyaml>=6.0.0
|
|
26
26
|
Requires-Dist: sqlalchemy>=2.0.0
|
|
27
27
|
Requires-Dist: alembic>=1.13.0
|
|
28
|
+
Requires-Dist: jsonata-python>=0.6.0
|
|
28
29
|
Provides-Extra: dev
|
|
29
30
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
30
31
|
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
@@ -53,6 +54,11 @@ Requires-Dist: pyspark>=3.5.0; extra == "worker"
|
|
|
53
54
|
Requires-Dist: redis>=5.0.0; extra == "worker"
|
|
54
55
|
Provides-Extra: etl
|
|
55
56
|
Requires-Dist: sshtunnel>=0.4.0; extra == "etl"
|
|
57
|
+
Requires-Dist: boto3>=1.26.0; extra == "etl"
|
|
58
|
+
Requires-Dist: google-cloud-storage>=2.0.0; extra == "etl"
|
|
59
|
+
Requires-Dist: azure-storage-blob>=12.0.0; extra == "etl"
|
|
60
|
+
Requires-Dist: openpyxl>=3.0.0; extra == "etl"
|
|
61
|
+
Requires-Dist: lxml>=4.9.0; extra == "etl"
|
|
56
62
|
Dynamic: license-file
|
|
57
63
|
|
|
58
64
|
# PyCharter
|
|
@@ -158,12 +164,15 @@ pycharter ui dev # Development mode with hot reload
|
|
|
158
164
|
|
|
159
165
|
## 🚀 Quick Start
|
|
160
166
|
|
|
167
|
+
### Quick Start: Convenience Functions (One-off Use)
|
|
168
|
+
|
|
161
169
|
```python
|
|
162
|
-
from pycharter import from_dict
|
|
170
|
+
from pycharter import from_dict, validate
|
|
163
171
|
|
|
164
172
|
# Define your JSON schema
|
|
165
173
|
schema = {
|
|
166
174
|
"type": "object",
|
|
175
|
+
"version": "1.0.0",
|
|
167
176
|
"properties": {
|
|
168
177
|
"name": {"type": "string"},
|
|
169
178
|
"age": {"type": "integer"},
|
|
@@ -172,15 +181,91 @@ schema = {
|
|
|
172
181
|
"required": ["name", "age"]
|
|
173
182
|
}
|
|
174
183
|
|
|
175
|
-
# Generate a Pydantic model
|
|
184
|
+
# Generate a Pydantic model (convenience function)
|
|
176
185
|
Person = from_dict(schema, "Person")
|
|
177
186
|
|
|
178
|
-
#
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
print(
|
|
187
|
+
# Validate data
|
|
188
|
+
result = validate(Person, {"name": "Alice", "age": 30, "email": "alice@example.com"})
|
|
189
|
+
if result.is_valid:
|
|
190
|
+
print(f"Valid: {result.data.name}") # Output: Valid: Alice
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Production Use: Validator Class (Recommended)
|
|
194
|
+
|
|
195
|
+
For production code with multiple validations, use the `Validator` class for better performance:
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from pycharter import Validator
|
|
199
|
+
|
|
200
|
+
# Create validator from contract directory or file
|
|
201
|
+
validator = Validator(contract_dir="data/contracts/user")
|
|
202
|
+
# Or: validator = Validator(contract_file="user_contract.yaml")
|
|
203
|
+
|
|
204
|
+
# Validate multiple records efficiently (model is cached)
|
|
205
|
+
result1 = validator.validate({"name": "Alice", "age": 30})
|
|
206
|
+
result2 = validator.validate({"name": "Bob", "age": 25})
|
|
207
|
+
|
|
208
|
+
# Batch validation
|
|
209
|
+
results = validator.validate_batch([data1, data2, data3])
|
|
182
210
|
```
|
|
183
211
|
|
|
212
|
+
### With Metadata Store
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
from pycharter import Validator, SQLiteMetadataStore
|
|
216
|
+
|
|
217
|
+
# Connect to metadata store
|
|
218
|
+
store = SQLiteMetadataStore("metadata.db")
|
|
219
|
+
store.connect()
|
|
220
|
+
|
|
221
|
+
# Create validator from store
|
|
222
|
+
validator = Validator(store=store, schema_id="user_schema_v1")
|
|
223
|
+
|
|
224
|
+
# Validate data
|
|
225
|
+
result = validator.validate({"name": "Alice", "age": 30})
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## 📐 API Organization
|
|
229
|
+
|
|
230
|
+
PyCharter's API is organized into **three tiers** to help you choose the right approach for your use case:
|
|
231
|
+
|
|
232
|
+
### Tier 1: Primary Interfaces (⭐ Recommended for Production)
|
|
233
|
+
|
|
234
|
+
**Classes** that provide the best performance and most features:
|
|
235
|
+
- **`Validator`** - Primary validation interface (use for multiple validations)
|
|
236
|
+
- **`QualityCheck`** - Primary quality assurance interface
|
|
237
|
+
- **`MetadataStoreClient`** - Base class for metadata stores
|
|
238
|
+
|
|
239
|
+
**When to use**: Production code, batch processing, when you need to validate multiple records.
|
|
240
|
+
|
|
241
|
+
### Tier 2: Convenience Functions (Quick Start)
|
|
242
|
+
|
|
243
|
+
**Functions** that make common tasks easy and discoverable:
|
|
244
|
+
- **Input helpers**: `from_dict()`, `from_file()`, `from_json()`, `from_url()`
|
|
245
|
+
- **Output helpers**: `to_dict()`, `to_file()`, `to_json()`
|
|
246
|
+
- **Validation helpers**: `validate_with_store()`, `validate_with_contract()`
|
|
247
|
+
- **Contract helpers**: `parse_contract_file()`, `build_contract()`
|
|
248
|
+
|
|
249
|
+
**When to use**: Quick scripts, one-off validations, exploratory work, learning the library.
|
|
250
|
+
|
|
251
|
+
### Tier 3: Low-Level Utilities
|
|
252
|
+
|
|
253
|
+
**Functions** for when you already have models or need fine-grained control:
|
|
254
|
+
- **`validate()`** - Validate with existing Pydantic model
|
|
255
|
+
- **`validate_batch()`** - Batch validate with existing model
|
|
256
|
+
- **`model_to_schema()`** - Core conversion function
|
|
257
|
+
|
|
258
|
+
**When to use**: Advanced use cases, when you've already generated models, custom workflows.
|
|
259
|
+
|
|
260
|
+
### Choosing the Right Approach
|
|
261
|
+
|
|
262
|
+
| Use Case | Recommended Approach | Example |
|
|
263
|
+
|----------|---------------------|---------|
|
|
264
|
+
| **Production pipeline with multiple validations** | `Validator` class | `validator = Validator(store=store, schema_id="schema"); validator.validate(data)` |
|
|
265
|
+
| **Quick one-off validation** | Convenience function | `validate_with_contract("contract.yaml", data)` |
|
|
266
|
+
| **You already have a model** | Low-level function | `validate(UserModel, data)` |
|
|
267
|
+
| **Batch processing** | `Validator.validate_batch()` | `validator.validate_batch([data1, data2, data3])` |
|
|
268
|
+
|
|
184
269
|
## 🏗️ Core Services & Data Production Journey
|
|
185
270
|
|
|
186
271
|
PyCharter provides **eight core services** that work together to support a complete data production journey, from contract specification to quality assurance. Each service plays a critical role in managing data contracts and ensuring data quality throughout your pipeline.
|
|
@@ -291,19 +376,20 @@ result = validate_with_contract(contract, {"name": "Alice", "age": "30"})
|
|
|
291
376
|
|
|
292
377
|
**Available Implementations**:
|
|
293
378
|
- **PostgresMetadataStore** - For PostgreSQL databases (recommended for production)
|
|
379
|
+
- **SQLiteMetadataStore** - For SQLite databases (great for development and small deployments)
|
|
294
380
|
- **MongoDBMetadataStore** - For MongoDB databases
|
|
295
381
|
- **RedisMetadataStore** - For Redis databases
|
|
296
382
|
- **InMemoryMetadataStore** - For testing and development (no persistence)
|
|
297
383
|
|
|
298
384
|
**Example**:
|
|
299
385
|
```python
|
|
300
|
-
from pycharter import
|
|
386
|
+
from pycharter import SQLiteMetadataStore, parse_contract_file
|
|
301
387
|
|
|
302
388
|
# Parse contract
|
|
303
389
|
metadata = parse_contract_file("contract.yaml")
|
|
304
390
|
|
|
305
|
-
# Use
|
|
306
|
-
store =
|
|
391
|
+
# Use SQLite metadata store (or PostgresMetadataStore, MongoDBMetadataStore, RedisMetadataStore, etc.)
|
|
392
|
+
store = SQLiteMetadataStore("metadata.db")
|
|
307
393
|
store.connect()
|
|
308
394
|
|
|
309
395
|
# Store decomposed components
|
|
@@ -415,6 +501,24 @@ ProductModel = from_dict(schema, "Product") # Round-trip
|
|
|
415
501
|
|
|
416
502
|
**When to Use**: In your data processing scripts, ETL pipelines, API endpoints, or any place where you need to validate incoming data against contract specifications.
|
|
417
503
|
|
|
504
|
+
**API Organization**:
|
|
505
|
+
|
|
506
|
+
PyCharter provides validation through three tiers:
|
|
507
|
+
|
|
508
|
+
1. **Tier 1: Validator Class** (⭐ **PRIMARY INTERFACE** - Recommended for production)
|
|
509
|
+
- Best performance for multiple validations (model is cached)
|
|
510
|
+
- Supports all data sources (contract files, directories, stores, dictionaries)
|
|
511
|
+
- Reusable instance for batch processing
|
|
512
|
+
|
|
513
|
+
2. **Tier 2: Convenience Functions** (Quick start - one-off validations)
|
|
514
|
+
- `validate_with_store()` - Quick validation with metadata store
|
|
515
|
+
- `validate_with_contract()` - Quick validation with contract file/dict
|
|
516
|
+
- `get_model_from_store()` / `get_model_from_contract()` - Get model for reuse
|
|
517
|
+
|
|
518
|
+
3. **Tier 3: Low-Level Functions** (When you already have a model)
|
|
519
|
+
- `validate()` - Validate single record with existing model
|
|
520
|
+
- `validate_batch()` - Batch validate with existing model
|
|
521
|
+
|
|
418
522
|
**How It Works**:
|
|
419
523
|
- Takes a Pydantic model (generated from a schema) and raw data
|
|
420
524
|
- Validates data against the model's constraints
|
|
@@ -422,55 +526,60 @@ ProductModel = from_dict(schema, "Product") # Round-trip
|
|
|
422
526
|
- Supports single record and batch validation
|
|
423
527
|
- Can be used in strict mode (raises exceptions) or lenient mode (returns results)
|
|
424
528
|
|
|
425
|
-
**
|
|
529
|
+
**Example - Validator Class (Recommended)**:
|
|
530
|
+
```python
|
|
531
|
+
from pycharter import Validator, SQLiteMetadataStore
|
|
426
532
|
|
|
427
|
-
1
|
|
428
|
-
|
|
429
|
-
|
|
533
|
+
# Option 1: From contract directory (no database)
|
|
534
|
+
validator = Validator(contract_dir="data/contracts/user")
|
|
535
|
+
result = validator.validate({"name": "Alice", "age": 30})
|
|
430
536
|
|
|
431
|
-
2
|
|
432
|
-
|
|
433
|
-
|
|
537
|
+
# Option 2: From metadata store (with database)
|
|
538
|
+
store = SQLiteMetadataStore("metadata.db")
|
|
539
|
+
store.connect()
|
|
540
|
+
validator = Validator(store=store, schema_id="user_schema_v1")
|
|
541
|
+
result = validator.validate({"name": "Alice", "age": 30})
|
|
434
542
|
|
|
435
|
-
|
|
543
|
+
# Option 3: From contract file
|
|
544
|
+
validator = Validator(contract_file="user_contract.yaml")
|
|
545
|
+
result = validator.validate({"name": "Alice", "age": 30})
|
|
546
|
+
|
|
547
|
+
# Batch validation (efficient - model cached)
|
|
548
|
+
results = validator.validate_batch([data1, data2, data3])
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
**Example - Convenience Functions (Quick Start)**:
|
|
436
552
|
```python
|
|
437
|
-
from pycharter import validate_with_store,
|
|
553
|
+
from pycharter import validate_with_store, validate_with_contract, SQLiteMetadataStore
|
|
438
554
|
|
|
439
|
-
#
|
|
440
|
-
store =
|
|
555
|
+
# Quick validation with store
|
|
556
|
+
store = SQLiteMetadataStore("metadata.db")
|
|
441
557
|
store.connect()
|
|
442
|
-
# ... store schema, rules, etc. ...
|
|
443
|
-
|
|
444
|
-
# Validate using store
|
|
445
558
|
result = validate_with_store(store, "user_schema_v1", {"name": "Alice", "age": 30})
|
|
446
|
-
|
|
447
|
-
|
|
559
|
+
|
|
560
|
+
# Quick validation with contract file (no database)
|
|
561
|
+
result = validate_with_contract("user_contract.yaml", {"name": "Alice", "age": 30})
|
|
448
562
|
```
|
|
449
563
|
|
|
450
|
-
**Example -
|
|
564
|
+
**Example - Low-Level (When You Have a Model)**:
|
|
451
565
|
```python
|
|
452
|
-
from pycharter import
|
|
566
|
+
from pycharter import from_dict, validate, validate_batch
|
|
453
567
|
|
|
454
|
-
#
|
|
455
|
-
|
|
456
|
-
"data/examples/book/book_contract.yaml",
|
|
457
|
-
{"isbn": "1234567890", "title": "Book", ...}
|
|
458
|
-
)
|
|
568
|
+
# Generate model
|
|
569
|
+
UserModel = from_dict(schema, "User")
|
|
459
570
|
|
|
460
|
-
#
|
|
461
|
-
|
|
462
|
-
result1 = validate(BookModel, data1)
|
|
463
|
-
result2 = validate(BookModel, data2)
|
|
571
|
+
# Validate single record
|
|
572
|
+
result = validate(UserModel, {"name": "Alice", "age": 30})
|
|
464
573
|
|
|
465
|
-
#
|
|
466
|
-
|
|
467
|
-
"schema": {"type": "object", "properties": {...}},
|
|
468
|
-
"coercion_rules": {"rules": {...}},
|
|
469
|
-
"validation_rules": {"rules": {...}}
|
|
470
|
-
}
|
|
471
|
-
result = validate_with_contract(contract, data)
|
|
574
|
+
# Batch validate
|
|
575
|
+
results = validate_batch(UserModel, [data1, data2, data3])
|
|
472
576
|
```
|
|
473
577
|
|
|
578
|
+
**Performance Tips**:
|
|
579
|
+
- ⚡ **For multiple validations**: Use `Validator` class (model is cached)
|
|
580
|
+
- ⚡ **For one-off validations**: Convenience functions are fine
|
|
581
|
+
- ⚡ **For batch processing**: Use `Validator.validate_batch()` or `validate_batch()`
|
|
582
|
+
|
|
474
583
|
**Contribution to Journey**: The runtime validator is the **enforcement layer** that ensures data quality in production. It validates actual data against contract specifications, catching violations early and preventing bad data from propagating through your systems. It supports both database-backed workflows (for production systems with metadata stores) and contract-based workflows (for simpler use cases without database dependencies).
|
|
475
584
|
|
|
476
585
|
---
|
|
@@ -533,9 +642,9 @@ Here's how all services work together in a complete data production journey:
|
|
|
533
642
|
```python
|
|
534
643
|
from pycharter import (
|
|
535
644
|
parse_contract_file,
|
|
536
|
-
|
|
645
|
+
SQLiteMetadataStore,
|
|
537
646
|
from_dict,
|
|
538
|
-
|
|
647
|
+
Validator,
|
|
539
648
|
to_dict
|
|
540
649
|
)
|
|
541
650
|
|
|
@@ -543,7 +652,7 @@ from pycharter import (
|
|
|
543
652
|
metadata = parse_contract_file("user_contract.yaml")
|
|
544
653
|
|
|
545
654
|
# Step 2: Store metadata in database
|
|
546
|
-
store =
|
|
655
|
+
store = SQLiteMetadataStore("metadata.db")
|
|
547
656
|
store.connect()
|
|
548
657
|
schema_id = store.store_schema("user", metadata.schema, version="1.0")
|
|
549
658
|
|
|
@@ -570,14 +679,27 @@ UserModel = from_dict(schema, "User")
|
|
|
570
679
|
schema_doc = to_dict(UserModel)
|
|
571
680
|
|
|
572
681
|
# Step 5: Validate data in production pipeline
|
|
682
|
+
# Option A: Using Validator class (recommended for production)
|
|
683
|
+
validator = Validator(store=store, schema_id=schema_id)
|
|
684
|
+
|
|
573
685
|
def process_user_data(raw_data):
|
|
574
|
-
result = validate(
|
|
686
|
+
result = validator.validate(raw_data)
|
|
575
687
|
if result.is_valid:
|
|
576
688
|
# Process validated data
|
|
577
689
|
return result.data
|
|
578
690
|
else:
|
|
579
691
|
# Handle validation errors
|
|
580
692
|
raise ValueError(f"Invalid data: {result.errors}")
|
|
693
|
+
|
|
694
|
+
# Option B: Using convenience function (quick start)
|
|
695
|
+
from pycharter import validate_with_store
|
|
696
|
+
|
|
697
|
+
def process_user_data_quick(raw_data):
|
|
698
|
+
result = validate_with_store(store, schema_id, raw_data)
|
|
699
|
+
if result.is_valid:
|
|
700
|
+
return result.data
|
|
701
|
+
else:
|
|
702
|
+
raise ValueError(f"Invalid data: {result.errors}")
|
|
581
703
|
```
|
|
582
704
|
|
|
583
705
|
---
|
|
@@ -646,12 +768,14 @@ Each service is designed to be **independent** yet **composable**, allowing you
|
|
|
646
768
|
|
|
647
769
|
### Basic Usage
|
|
648
770
|
|
|
771
|
+
**Using Convenience Functions** (Quick Start):
|
|
649
772
|
```python
|
|
650
773
|
from pycharter import from_dict, from_json, from_file
|
|
651
774
|
|
|
652
775
|
# From dictionary
|
|
653
776
|
schema = {
|
|
654
777
|
"type": "object",
|
|
778
|
+
"version": "1.0.0",
|
|
655
779
|
"properties": {
|
|
656
780
|
"title": {"type": "string"},
|
|
657
781
|
"published": {"type": "boolean", "default": False}
|
|
@@ -660,13 +784,26 @@ schema = {
|
|
|
660
784
|
Article = from_dict(schema, "Article")
|
|
661
785
|
|
|
662
786
|
# From JSON string
|
|
663
|
-
schema_json = '{"type": "object", "properties": {"name": {"type": "string"}}}'
|
|
787
|
+
schema_json = '{"type": "object", "version": "1.0.0", "properties": {"name": {"type": "string"}}}'
|
|
664
788
|
User = from_json(schema_json, "User")
|
|
665
789
|
|
|
666
790
|
# From file
|
|
667
791
|
Product = from_file("product_schema.json", "Product")
|
|
668
792
|
```
|
|
669
793
|
|
|
794
|
+
**Using Validator Class** (Production):
|
|
795
|
+
```python
|
|
796
|
+
from pycharter import Validator
|
|
797
|
+
|
|
798
|
+
# From contract directory
|
|
799
|
+
validator = Validator(contract_dir="data/contracts/article")
|
|
800
|
+
result = validator.validate({"title": "My Article", "published": True})
|
|
801
|
+
|
|
802
|
+
# From contract file
|
|
803
|
+
validator = Validator(contract_file="article_contract.yaml")
|
|
804
|
+
result = validator.validate({"title": "My Article", "published": True})
|
|
805
|
+
```
|
|
806
|
+
|
|
670
807
|
### Nested Objects
|
|
671
808
|
|
|
672
809
|
```python
|
|
@@ -674,6 +811,7 @@ from pycharter import from_dict
|
|
|
674
811
|
|
|
675
812
|
schema = {
|
|
676
813
|
"type": "object",
|
|
814
|
+
"version": "1.0.0",
|
|
677
815
|
"properties": {
|
|
678
816
|
"name": {"type": "string"},
|
|
679
817
|
"address": {
|
|
@@ -707,6 +845,7 @@ from pycharter import from_dict
|
|
|
707
845
|
|
|
708
846
|
schema = {
|
|
709
847
|
"type": "object",
|
|
848
|
+
"version": "1.0.0",
|
|
710
849
|
"properties": {
|
|
711
850
|
"tags": {
|
|
712
851
|
"type": "array",
|
|
@@ -739,13 +878,14 @@ print(cart.items[0].name) # Output: Apple
|
|
|
739
878
|
|
|
740
879
|
### Coercion and Validation
|
|
741
880
|
|
|
742
|
-
|
|
881
|
+
PyCharter supports **coercion** (pre-validation transformation) and **validation** (post-validation checks):
|
|
743
882
|
|
|
744
883
|
```python
|
|
745
884
|
from pycharter import from_dict
|
|
746
885
|
|
|
747
886
|
schema = {
|
|
748
887
|
"type": "object",
|
|
888
|
+
"version": "1.0.0",
|
|
749
889
|
"properties": {
|
|
750
890
|
"flight_number": {
|
|
751
891
|
"type": "integer",
|
|
@@ -871,13 +1011,88 @@ register_validation("must_be_positive", must_be_positive)
|
|
|
871
1011
|
|
|
872
1012
|
## 📖 API Reference
|
|
873
1013
|
|
|
874
|
-
|
|
1014
|
+
PyCharter's API is organized into three tiers to help you choose the right approach:
|
|
875
1015
|
|
|
1016
|
+
### Tier 1: Primary Interfaces (Classes - Best Performance)
|
|
1017
|
+
|
|
1018
|
+
**Validator** - Primary validation interface (recommended for production)
|
|
1019
|
+
```python
|
|
1020
|
+
from pycharter import Validator
|
|
1021
|
+
|
|
1022
|
+
# Create validator from various sources
|
|
1023
|
+
validator = Validator(contract_dir="data/contracts/user")
|
|
1024
|
+
validator = Validator(contract_file="contract.yaml")
|
|
1025
|
+
validator = Validator(store=store, schema_id="user_schema")
|
|
1026
|
+
validator = Validator(contract_dict={...})
|
|
1027
|
+
|
|
1028
|
+
# Validate data
|
|
1029
|
+
result = validator.validate(data)
|
|
1030
|
+
results = validator.validate_batch([data1, data2])
|
|
1031
|
+
model = validator.get_model() # Get the generated Pydantic model
|
|
1032
|
+
```
|
|
1033
|
+
|
|
1034
|
+
**QualityCheck** - Primary quality assurance interface
|
|
1035
|
+
```python
|
|
1036
|
+
from pycharter import QualityCheck, QualityCheckOptions
|
|
1037
|
+
|
|
1038
|
+
check = QualityCheck(store=store)
|
|
1039
|
+
report = check.run(schema_id="user_schema", data=data, options=QualityCheckOptions(...))
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1042
|
+
**MetadataStoreClient** - Base class for metadata stores
|
|
1043
|
+
```python
|
|
1044
|
+
from pycharter import MetadataStoreClient, SQLiteMetadataStore, PostgresMetadataStore
|
|
1045
|
+
|
|
1046
|
+
store = SQLiteMetadataStore("metadata.db")
|
|
1047
|
+
store.connect()
|
|
1048
|
+
```
|
|
1049
|
+
|
|
1050
|
+
### Tier 2: Convenience Functions (Quick Start)
|
|
1051
|
+
|
|
1052
|
+
**Pydantic Generator** - Input type helpers
|
|
876
1053
|
- **`from_dict(schema: dict, model_name: str = "DynamicModel")`** - Create model from dictionary
|
|
877
1054
|
- **`from_json(json_string: str, model_name: str = "DynamicModel")`** - Create model from JSON string
|
|
878
|
-
- **`from_file(file_path: str, model_name: str = None)`** - Create model from JSON
|
|
1055
|
+
- **`from_file(file_path: str, model_name: str = None)`** - Create model from file (JSON/YAML)
|
|
879
1056
|
- **`from_url(url: str, model_name: str = "DynamicModel")`** - Create model from URL
|
|
880
|
-
- **`
|
|
1057
|
+
- **`generate_model(schema: dict, model_name: str = "DynamicModel")`** - Advanced: more control
|
|
1058
|
+
- **`generate_model_file(schema: dict, output_path: str, model_name: str = "DynamicModel")`** - Generate and save to file
|
|
1059
|
+
|
|
1060
|
+
**JSON Schema Converter** - Output type helpers
|
|
1061
|
+
- **`to_dict(model: Type[BaseModel], ...)`** - Convert model to JSON Schema dictionary
|
|
1062
|
+
- **`to_file(model: Type[BaseModel], file_path: str, ...)`** - Convert model to file
|
|
1063
|
+
- **`to_json(model: Type[BaseModel], ...)`** - Convert model to JSON string
|
|
1064
|
+
- **`model_to_schema(model: Type[BaseModel], ...)`** - Advanced: core conversion function
|
|
1065
|
+
|
|
1066
|
+
**Runtime Validator** - Data source helpers
|
|
1067
|
+
- **`validate_with_store(store, schema_id, data, ...)`** - Quick validation with metadata store
|
|
1068
|
+
- **`validate_batch_with_store(store, schema_id, data_list, ...)`** - Batch validation with store
|
|
1069
|
+
- **`validate_with_contract(contract, data, ...)`** - Quick validation with contract file/dict
|
|
1070
|
+
- **`validate_batch_with_contract(contract, data_list, ...)`** - Batch validation with contract
|
|
1071
|
+
- **`get_model_from_store(store, schema_id, ...)`** - Get model from metadata store
|
|
1072
|
+
- **`get_model_from_contract(contract, ...)`** - Get model from contract
|
|
1073
|
+
- **`validate_input(contract, ...)`** - Decorator for function input validation
|
|
1074
|
+
- **`validate_output(contract, ...)`** - Decorator for function output validation
|
|
1075
|
+
- **`validate_with_contract_decorator(contract, ...)`** - Decorator for contract-based validation
|
|
1076
|
+
|
|
1077
|
+
**Contract Management**
|
|
1078
|
+
- **`parse_contract(contract_dict: dict)`** - Parse contract dictionary
|
|
1079
|
+
- **`parse_contract_file(file_path: str)`** - Parse contract file (YAML/JSON)
|
|
1080
|
+
- **`build_contract(artifacts: ContractArtifacts)`** - Build contract from artifacts
|
|
1081
|
+
- **`build_contract_from_store(store, schema_id, ...)`** - Build contract from metadata store
|
|
1082
|
+
|
|
1083
|
+
### Tier 3: Low-Level Utilities (When You Have Models)
|
|
1084
|
+
|
|
1085
|
+
- **`validate(model: Type[BaseModel], data: dict, strict: bool = False)`** - Validate single record
|
|
1086
|
+
- **`validate_batch(model: Type[BaseModel], data_list: List[dict], strict: bool = False)`** - Batch validate
|
|
1087
|
+
- **`ValidationResult`** - Result class with `is_valid`, `data`, and `errors` attributes
|
|
1088
|
+
|
|
1089
|
+
### Metadata Store Implementations
|
|
1090
|
+
|
|
1091
|
+
- **`InMemoryMetadataStore()`** - In-memory store (testing/development)
|
|
1092
|
+
- **`SQLiteMetadataStore(database_path: str)`** - SQLite database
|
|
1093
|
+
- **`PostgresMetadataStore(connection_string: str)`** - PostgreSQL database
|
|
1094
|
+
- **`MongoDBMetadataStore(connection_string: str)`** - MongoDB database
|
|
1095
|
+
- **`RedisMetadataStore(connection_string: str)`** - Redis database
|
|
881
1096
|
|
|
882
1097
|
## 🎯 Design Principles & Requirements
|
|
883
1098
|
|
|
@@ -979,21 +1194,33 @@ pytest -k "coercion"
|
|
|
979
1194
|
|
|
980
1195
|
## 📦 Publishing to PyPI
|
|
981
1196
|
|
|
1197
|
+
**Automatic publishing via GitHub Releases (Trusted Publishing - no tokens needed!):**
|
|
1198
|
+
|
|
982
1199
|
```bash
|
|
983
|
-
# Update version in pyproject.toml
|
|
984
|
-
#
|
|
985
|
-
|
|
1200
|
+
# 1. Update version in pyproject.toml
|
|
1201
|
+
# version = "0.0.21"
|
|
1202
|
+
|
|
1203
|
+
# 2. Commit and push
|
|
1204
|
+
git add pyproject.toml
|
|
1205
|
+
git commit -m "Bump version to 0.0.21"
|
|
1206
|
+
git push
|
|
986
1207
|
|
|
987
|
-
#
|
|
988
|
-
|
|
1208
|
+
# 3. Create GitHub Release (automatically publishes to PyPI)
|
|
1209
|
+
gh release create v0.0.21 --title "v0.0.21" --notes "Release notes"
|
|
1210
|
+
```
|
|
989
1211
|
|
|
990
|
-
|
|
991
|
-
|
|
1212
|
+
The workflow automatically:
|
|
1213
|
+
- ✅ Builds UI
|
|
1214
|
+
- ✅ Builds Python package
|
|
1215
|
+
- ✅ Publishes to PyPI (using Trusted Publishing)
|
|
992
1216
|
|
|
993
|
-
|
|
994
|
-
|
|
1217
|
+
**Local build:**
|
|
1218
|
+
```bash
|
|
1219
|
+
make build # Builds package (UI built automatically via setup.py)
|
|
995
1220
|
```
|
|
996
1221
|
|
|
1222
|
+
See `PUBLISHING.md` for complete documentation.
|
|
1223
|
+
|
|
997
1224
|
## 📋 JSON Schema Compliance
|
|
998
1225
|
|
|
999
1226
|
PyCharter is fully compliant with **JSON Schema Draft 2020-12** standard:
|