pycharter 0.0.19__tar.gz → 0.0.22__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.
Files changed (379) hide show
  1. {pycharter-0.0.19 → pycharter-0.0.22}/MANIFEST.in +6 -1
  2. {pycharter-0.0.19/pycharter.egg-info → pycharter-0.0.22}/PKG-INFO +284 -62
  3. {pycharter-0.0.19 → pycharter-0.0.22}/README.md +282 -61
  4. {pycharter-0.0.19 → pycharter-0.0.22}/api/dependencies/__init__.py +2 -1
  5. {pycharter-0.0.19 → pycharter-0.0.22}/api/dependencies/database.py +71 -5
  6. {pycharter-0.0.19 → pycharter-0.0.22}/api/main.py +47 -8
  7. {pycharter-0.0.19 → pycharter-0.0.22}/api/models/contracts.py +6 -4
  8. {pycharter-0.0.19 → pycharter-0.0.22}/api/models/metadata.py +11 -7
  9. {pycharter-0.0.19 → pycharter-0.0.22}/api/models/schemas.py +16 -10
  10. {pycharter-0.0.19 → pycharter-0.0.22}/api/routes/v1/contracts.py +498 -226
  11. {pycharter-0.0.19 → pycharter-0.0.22}/api/routes/v1/metadata.py +52 -211
  12. {pycharter-0.0.19 → pycharter-0.0.22}/api/routes/v1/schemas.py +1 -1
  13. {pycharter-0.0.19 → pycharter-0.0.22}/api/routes/v1/settings.py +88 -1
  14. pycharter-0.0.22/api/utils.py +224 -0
  15. pycharter-0.0.22/pycharter/__init__.py +211 -0
  16. pycharter-0.0.22/pycharter/data/templates/template_transform_advanced.yaml +50 -0
  17. pycharter-0.0.22/pycharter/data/templates/template_transform_simple.yaml +59 -0
  18. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/base.py +1 -2
  19. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/etl_generator/orchestrator.py +463 -487
  20. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/metadata_store/postgres.py +16 -191
  21. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/metadata_store/sqlite.py +12 -41
  22. {pycharter-0.0.19 → pycharter-0.0.22/pycharter.egg-info}/PKG-INFO +284 -62
  23. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter.egg-info/SOURCES.txt +138 -2
  24. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter.egg-info/requires.txt +1 -0
  25. {pycharter-0.0.19 → pycharter-0.0.22}/pyproject.toml +5 -1
  26. pycharter-0.0.22/ui/static/404/index.html +1 -0
  27. pycharter-0.0.22/ui/static/404.html +1 -0
  28. pycharter-0.0.22/ui/static/__next.__PAGE__.txt +10 -0
  29. pycharter-0.0.22/ui/static/__next._full.txt +30 -0
  30. pycharter-0.0.22/ui/static/__next._head.txt +7 -0
  31. pycharter-0.0.22/ui/static/__next._index.txt +9 -0
  32. pycharter-0.0.22/ui/static/__next._tree.txt +2 -0
  33. pycharter-0.0.22/ui/static/_next/static/0rYA78L88aUyD2Uh38hhX/_buildManifest.js +11 -0
  34. pycharter-0.0.22/ui/static/_next/static/0rYA78L88aUyD2Uh38hhX/_ssgManifest.js +1 -0
  35. pycharter-0.0.22/ui/static/_next/static/chunks/13d4a0fbd74c1ee4.js +1 -0
  36. pycharter-0.0.22/ui/static/_next/static/chunks/222442f6da32302a.js +1 -0
  37. pycharter-0.0.22/ui/static/_next/static/chunks/247eb132b7f7b574.js +1 -0
  38. pycharter-0.0.22/ui/static/_next/static/chunks/297d55555b71baba.js +1 -0
  39. pycharter-0.0.22/ui/static/_next/static/chunks/2ab439ce003cd691.js +1 -0
  40. pycharter-0.0.22/ui/static/_next/static/chunks/2edb43b48432ac04.js +441 -0
  41. pycharter-0.0.22/ui/static/_next/static/chunks/414e77373f8ff61c.js +1 -0
  42. pycharter-0.0.22/ui/static/_next/static/chunks/49ca65abd26ae49e.js +1 -0
  43. pycharter-0.0.22/ui/static/_next/static/chunks/5e04d10c4a7b58a3.js +1 -0
  44. pycharter-0.0.22/ui/static/_next/static/chunks/652ad0aa26265c47.js +2 -0
  45. pycharter-0.0.22/ui/static/_next/static/chunks/75d88a058d8ffaa6.js +1 -0
  46. pycharter-0.0.22/ui/static/_next/static/chunks/8c89634cf6bad76f.js +1 -0
  47. pycharter-0.0.22/ui/static/_next/static/chunks/9667e7a3d359eb39.js +1 -0
  48. pycharter-0.0.22/ui/static/_next/static/chunks/9c23f44fff36548a.js +1 -0
  49. pycharter-0.0.22/ui/static/_next/static/chunks/a6dad97d9634a72d.js +1 -0
  50. pycharter-0.0.22/ui/static/_next/static/chunks/b32a0963684b9933.js +4 -0
  51. pycharter-0.0.22/ui/static/_next/static/chunks/c4fa4f4114b7c352.js +1 -0
  52. pycharter-0.0.22/ui/static/_next/static/chunks/c69f6cba366bd988.js +1 -0
  53. pycharter-0.0.22/ui/static/_next/static/chunks/d2363397e1b2bcab.css +1 -0
  54. pycharter-0.0.22/ui/static/_next/static/chunks/db913959c675cea6.js +1 -0
  55. pycharter-0.0.22/ui/static/_next/static/chunks/f061a4be97bfc3b3.js +1 -0
  56. pycharter-0.0.22/ui/static/_next/static/chunks/f2e7afeab1178138.js +1 -0
  57. pycharter-0.0.22/ui/static/_next/static/chunks/f7d1a90dd75d2572.js +1 -0
  58. pycharter-0.0.22/ui/static/_next/static/chunks/ff1a16fafef87110.js +1 -0
  59. pycharter-0.0.22/ui/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +3 -0
  60. pycharter-0.0.22/ui/static/_not-found/__next._full.txt +17 -0
  61. pycharter-0.0.22/ui/static/_not-found/__next._head.txt +7 -0
  62. pycharter-0.0.22/ui/static/_not-found/__next._index.txt +9 -0
  63. pycharter-0.0.22/ui/static/_not-found/__next._not-found.__PAGE__.txt +5 -0
  64. pycharter-0.0.22/ui/static/_not-found/__next._not-found.txt +4 -0
  65. pycharter-0.0.22/ui/static/_not-found/__next._tree.txt +2 -0
  66. pycharter-0.0.22/ui/static/_not-found/index.html +1 -0
  67. pycharter-0.0.22/ui/static/_not-found/index.txt +17 -0
  68. pycharter-0.0.22/ui/static/contracts/__next._full.txt +21 -0
  69. pycharter-0.0.22/ui/static/contracts/__next._head.txt +7 -0
  70. pycharter-0.0.22/ui/static/contracts/__next._index.txt +9 -0
  71. pycharter-0.0.22/ui/static/contracts/__next._tree.txt +2 -0
  72. pycharter-0.0.22/ui/static/contracts/__next.contracts.__PAGE__.txt +9 -0
  73. pycharter-0.0.22/ui/static/contracts/__next.contracts.txt +4 -0
  74. pycharter-0.0.22/ui/static/contracts/index.html +1 -0
  75. pycharter-0.0.22/ui/static/contracts/index.txt +21 -0
  76. pycharter-0.0.22/ui/static/documentation/__next._full.txt +21 -0
  77. pycharter-0.0.22/ui/static/documentation/__next._head.txt +7 -0
  78. pycharter-0.0.22/ui/static/documentation/__next._index.txt +9 -0
  79. pycharter-0.0.22/ui/static/documentation/__next._tree.txt +2 -0
  80. pycharter-0.0.22/ui/static/documentation/__next.documentation.__PAGE__.txt +9 -0
  81. pycharter-0.0.22/ui/static/documentation/__next.documentation.txt +4 -0
  82. pycharter-0.0.22/ui/static/documentation/index.html +93 -0
  83. pycharter-0.0.22/ui/static/documentation/index.txt +21 -0
  84. pycharter-0.0.22/ui/static/index.html +1 -0
  85. pycharter-0.0.22/ui/static/index.txt +30 -0
  86. pycharter-0.0.22/ui/static/metadata/__next._full.txt +21 -0
  87. pycharter-0.0.22/ui/static/metadata/__next._head.txt +7 -0
  88. pycharter-0.0.22/ui/static/metadata/__next._index.txt +9 -0
  89. pycharter-0.0.22/ui/static/metadata/__next._tree.txt +2 -0
  90. pycharter-0.0.22/ui/static/metadata/__next.metadata.__PAGE__.txt +9 -0
  91. pycharter-0.0.22/ui/static/metadata/__next.metadata.txt +4 -0
  92. pycharter-0.0.22/ui/static/metadata/index.html +1 -0
  93. pycharter-0.0.22/ui/static/metadata/index.txt +21 -0
  94. pycharter-0.0.22/ui/static/quality/__next._full.txt +21 -0
  95. pycharter-0.0.22/ui/static/quality/__next._head.txt +7 -0
  96. pycharter-0.0.22/ui/static/quality/__next._index.txt +9 -0
  97. pycharter-0.0.22/ui/static/quality/__next._tree.txt +2 -0
  98. pycharter-0.0.22/ui/static/quality/__next.quality.__PAGE__.txt +9 -0
  99. pycharter-0.0.22/ui/static/quality/__next.quality.txt +4 -0
  100. pycharter-0.0.22/ui/static/quality/index.html +2 -0
  101. pycharter-0.0.22/ui/static/quality/index.txt +21 -0
  102. pycharter-0.0.22/ui/static/rules/__next._full.txt +21 -0
  103. pycharter-0.0.22/ui/static/rules/__next._head.txt +7 -0
  104. pycharter-0.0.22/ui/static/rules/__next._index.txt +9 -0
  105. pycharter-0.0.22/ui/static/rules/__next._tree.txt +2 -0
  106. pycharter-0.0.22/ui/static/rules/__next.rules.__PAGE__.txt +9 -0
  107. pycharter-0.0.22/ui/static/rules/__next.rules.txt +4 -0
  108. pycharter-0.0.22/ui/static/rules/index.html +1 -0
  109. pycharter-0.0.22/ui/static/rules/index.txt +21 -0
  110. pycharter-0.0.22/ui/static/schemas/__next._full.txt +21 -0
  111. pycharter-0.0.22/ui/static/schemas/__next._head.txt +7 -0
  112. pycharter-0.0.22/ui/static/schemas/__next._index.txt +9 -0
  113. pycharter-0.0.22/ui/static/schemas/__next._tree.txt +2 -0
  114. pycharter-0.0.22/ui/static/schemas/__next.schemas.__PAGE__.txt +9 -0
  115. pycharter-0.0.22/ui/static/schemas/__next.schemas.txt +4 -0
  116. pycharter-0.0.22/ui/static/schemas/index.html +1 -0
  117. pycharter-0.0.22/ui/static/schemas/index.txt +21 -0
  118. pycharter-0.0.22/ui/static/settings/__next._full.txt +21 -0
  119. pycharter-0.0.22/ui/static/settings/__next._head.txt +7 -0
  120. pycharter-0.0.22/ui/static/settings/__next._index.txt +9 -0
  121. pycharter-0.0.22/ui/static/settings/__next._tree.txt +2 -0
  122. pycharter-0.0.22/ui/static/settings/__next.settings.__PAGE__.txt +9 -0
  123. pycharter-0.0.22/ui/static/settings/__next.settings.txt +4 -0
  124. pycharter-0.0.22/ui/static/settings/index.html +1 -0
  125. pycharter-0.0.22/ui/static/settings/index.txt +21 -0
  126. pycharter-0.0.22/ui/static/static/.gitkeep +0 -0
  127. pycharter-0.0.22/ui/static/static/_next/static/chunks/222442f6da32302a.js +1 -0
  128. pycharter-0.0.22/ui/static/static/_next/static/chunks/247eb132b7f7b574.js +1 -0
  129. pycharter-0.0.22/ui/static/static/_next/static/chunks/297d55555b71baba.js +1 -0
  130. pycharter-0.0.22/ui/static/static/_next/static/chunks/2ab439ce003cd691.js +1 -0
  131. pycharter-0.0.22/ui/static/static/_next/static/chunks/414e77373f8ff61c.js +1 -0
  132. pycharter-0.0.22/ui/static/static/_next/static/chunks/49ca65abd26ae49e.js +1 -0
  133. pycharter-0.0.22/ui/static/static/_next/static/chunks/5e04d10c4a7b58a3.js +1 -0
  134. pycharter-0.0.22/ui/static/static/_next/static/chunks/5fc14c00a2779dc5.js +1 -0
  135. pycharter-0.0.22/ui/static/static/_next/static/chunks/652ad0aa26265c47.js +2 -0
  136. pycharter-0.0.22/ui/static/static/_next/static/chunks/75d88a058d8ffaa6.js +1 -0
  137. pycharter-0.0.22/ui/static/static/_next/static/chunks/8c89634cf6bad76f.js +1 -0
  138. pycharter-0.0.22/ui/static/static/_next/static/chunks/9667e7a3d359eb39.js +1 -0
  139. pycharter-0.0.22/ui/static/static/_next/static/chunks/9c23f44fff36548a.js +1 -0
  140. pycharter-0.0.22/ui/static/static/_next/static/chunks/a6dad97d9634a72d.js +1 -0
  141. pycharter-0.0.22/ui/static/static/_next/static/chunks/b32a0963684b9933.js +4 -0
  142. pycharter-0.0.22/ui/static/static/_next/static/chunks/b584574fdc8ab13e.js +1 -0
  143. pycharter-0.0.22/ui/static/static/_next/static/chunks/c69f6cba366bd988.js +1 -0
  144. pycharter-0.0.22/ui/static/static/_next/static/chunks/d5989c94d3614b3a.js +158 -0
  145. pycharter-0.0.22/ui/static/static/_next/static/chunks/db913959c675cea6.js +1 -0
  146. pycharter-0.0.22/ui/static/static/_next/static/chunks/f061a4be97bfc3b3.js +1 -0
  147. pycharter-0.0.22/ui/static/static/_next/static/chunks/f2e7afeab1178138.js +1 -0
  148. pycharter-0.0.22/ui/static/static/_next/static/chunks/ff1a16fafef87110.js +1 -0
  149. pycharter-0.0.22/ui/static/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +3 -0
  150. pycharter-0.0.22/ui/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_buildManifest.js +11 -0
  151. pycharter-0.0.22/ui/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_ssgManifest.js +1 -0
  152. pycharter-0.0.22/ui/static/validation/__next._full.txt +21 -0
  153. pycharter-0.0.22/ui/static/validation/__next._head.txt +7 -0
  154. pycharter-0.0.22/ui/static/validation/__next._index.txt +9 -0
  155. pycharter-0.0.22/ui/static/validation/__next._tree.txt +2 -0
  156. pycharter-0.0.22/ui/static/validation/__next.validation.__PAGE__.txt +9 -0
  157. pycharter-0.0.22/ui/static/validation/__next.validation.txt +4 -0
  158. pycharter-0.0.22/ui/static/validation/index.html +1 -0
  159. pycharter-0.0.22/ui/static/validation/index.txt +21 -0
  160. pycharter-0.0.19/pycharter/__init__.py +0 -155
  161. pycharter-0.0.19/pycharter/db/schemas/.ipynb_checkpoints/data_contract-checkpoint.py +0 -160
  162. {pycharter-0.0.19 → pycharter-0.0.22}/LICENSE +0 -0
  163. {pycharter-0.0.19 → pycharter-0.0.22}/api/__init__.py +0 -0
  164. {pycharter-0.0.19 → pycharter-0.0.22}/api/dependencies/store.py +0 -0
  165. {pycharter-0.0.19 → pycharter-0.0.22}/api/models/__init__.py +0 -0
  166. {pycharter-0.0.19 → pycharter-0.0.22}/api/models/metadata_entities.py +0 -0
  167. {pycharter-0.0.19 → pycharter-0.0.22}/api/models/quality.py +0 -0
  168. {pycharter-0.0.19 → pycharter-0.0.22}/api/models/validation.py +0 -0
  169. {pycharter-0.0.19 → pycharter-0.0.22}/api/routes/__init__.py +0 -0
  170. {pycharter-0.0.19 → pycharter-0.0.22}/api/routes/v1/__init__.py +0 -0
  171. {pycharter-0.0.19 → pycharter-0.0.22}/api/routes/v1/quality.py +0 -0
  172. {pycharter-0.0.19 → pycharter-0.0.22}/api/routes/v1/templates.py +0 -0
  173. {pycharter-0.0.19 → pycharter-0.0.22}/api/routes/v1/validation.py +0 -0
  174. {pycharter-0.0.19 → pycharter-0.0.22}/api/routes/v1/validation_jobs.py +0 -0
  175. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/cli.py +0 -0
  176. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/config.py +0 -0
  177. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/contract_builder/__init__.py +0 -0
  178. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/contract_builder/builder.py +0 -0
  179. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/contract_parser/__init__.py +0 -0
  180. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/contract_parser/parser.py +0 -0
  181. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/data/__init__.py +0 -0
  182. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/data/templates/template_coercion_rules.yaml +0 -0
  183. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/data/templates/template_contract.yaml +0 -0
  184. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/data/templates/template_metadata.yaml +0 -0
  185. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/data/templates/template_schema.yaml +0 -0
  186. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/data/templates/template_validation_rules.yaml +0 -0
  187. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/__init__.py +0 -0
  188. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/cli.py +0 -0
  189. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/migrations/README +0 -0
  190. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/migrations/env.py +0 -0
  191. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/migrations/script.py.mako +0 -0
  192. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/migrations/versions/20250115120000_add_tier2_tier3_entities.py +0 -0
  193. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/migrations/versions/20251209163657_799b73fe9f6c_initial_schema.py +0 -0
  194. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/migrations/versions/20251209164144_ae0efda02aa1_initial_schema.py +0 -0
  195. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/migrations/versions/20251217160146_f9995dc0f4b3_add_quality_tables.py +0 -0
  196. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/migrations/versions/20251217164915_8b08d78068e3_add_data_version_tracking.py +0 -0
  197. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/migrations/versions/20260110083000_a1b2c3d4e5f6_add_dead_letter_queue_table.py +0 -0
  198. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/migrations/versions/20260120000000_add_name_title_validation_constraints.py +0 -0
  199. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/migrations/versions/20260121000000_remove_artifact_versions_from_data_contracts.py +0 -0
  200. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/migrations/versions/20260122000000_change_artifact_unique_constraints_to_title_version.py +0 -0
  201. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/migrations/versions/__init__.py +0 -0
  202. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/__init__.py +0 -0
  203. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/api_endpoint.py +0 -0
  204. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/coercion_rule.py +0 -0
  205. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/compliance_framework.py +0 -0
  206. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/data_contract.py +0 -0
  207. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/data_dependency.py +0 -0
  208. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/data_feed.py +0 -0
  209. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/dlq.py +0 -0
  210. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/domain.py +0 -0
  211. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/environment.py +0 -0
  212. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/metadata_record.py +0 -0
  213. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/owner.py +0 -0
  214. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/quality_metric.py +0 -0
  215. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/quality_violation.py +0 -0
  216. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/schema.py +0 -0
  217. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/storage_location.py +0 -0
  218. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/system.py +0 -0
  219. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/tag.py +0 -0
  220. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/models/validation_rule.py +0 -0
  221. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/schemas/__init__.py +0 -0
  222. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/db/schemas/data_contract.py +0 -0
  223. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/etl_generator/__init__.py +0 -0
  224. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/etl_generator/checkpoint.py +0 -0
  225. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/etl_generator/config_generator.py +0 -0
  226. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/etl_generator/database.py +0 -0
  227. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/etl_generator/dlq.py +0 -0
  228. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/etl_generator/extraction.py +0 -0
  229. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/etl_generator/factory.py +0 -0
  230. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/etl_generator/progress.py +0 -0
  231. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/integrations/__init__.py +0 -0
  232. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/integrations/kafka.py +0 -0
  233. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/integrations/streaming.py +0 -0
  234. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/json_schema_converter/__init__.py +0 -0
  235. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/json_schema_converter/converter.py +0 -0
  236. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/json_schema_converter/reverse_converter.py +0 -0
  237. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/metadata_store/__init__.py +0 -0
  238. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/metadata_store/client.py +0 -0
  239. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/metadata_store/in_memory.py +0 -0
  240. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/metadata_store/mongodb.py +0 -0
  241. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/metadata_store/redis.py +0 -0
  242. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/py.typed +0 -0
  243. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/pydantic_generator/__init__.py +0 -0
  244. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/pydantic_generator/converter.py +0 -0
  245. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/pydantic_generator/generator.py +0 -0
  246. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/quality/__init__.py +0 -0
  247. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/quality/check.py +0 -0
  248. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/quality/cli.py +0 -0
  249. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/quality/metrics.py +0 -0
  250. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/quality/models.py +0 -0
  251. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/quality/profiling.py +0 -0
  252. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/quality/violations.py +0 -0
  253. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/runtime_validator/__init__.py +0 -0
  254. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/runtime_validator/decorators.py +0 -0
  255. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/runtime_validator/utils.py +0 -0
  256. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/runtime_validator/validator.py +0 -0
  257. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/runtime_validator/validator_core.py +0 -0
  258. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/runtime_validator/wrappers.py +0 -0
  259. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/shared/__init__.py +0 -0
  260. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/shared/coercions/__init__.py +0 -0
  261. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/shared/coercions/builtin.py +0 -0
  262. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/shared/json_schema_support.py +0 -0
  263. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/shared/json_schema_validator.py +0 -0
  264. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/shared/name_validator.py +0 -0
  265. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/shared/schema_parser.py +0 -0
  266. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/shared/schema_resolver.py +0 -0
  267. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/shared/validations/__init__.py +0 -0
  268. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/shared/validations/builtin.py +0 -0
  269. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/utils/__init__.py +0 -0
  270. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/utils/value_injector.py +0 -0
  271. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter/utils/version.py +0 -0
  272. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter.egg-info/dependency_links.txt +0 -0
  273. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter.egg-info/entry_points.txt +0 -0
  274. {pycharter-0.0.19 → pycharter-0.0.22}/pycharter.egg-info/top_level.txt +0 -0
  275. {pycharter-0.0.19 → pycharter-0.0.22}/setup.cfg +0 -0
  276. {pycharter-0.0.19 → pycharter-0.0.22}/setup.py +0 -0
  277. {pycharter-0.0.19 → pycharter-0.0.22}/tests/test_contract_builder.py +0 -0
  278. {pycharter-0.0.19 → pycharter-0.0.22}/tests/test_contract_parser.py +0 -0
  279. {pycharter-0.0.19 → pycharter-0.0.22}/tests/test_integration.py +0 -0
  280. {pycharter-0.0.19 → pycharter-0.0.22}/tests/test_json_schema_compliance.py +0 -0
  281. {pycharter-0.0.19 → pycharter-0.0.22}/tests/test_json_schema_converter.py +0 -0
  282. {pycharter-0.0.19 → pycharter-0.0.22}/tests/test_metadata_stores.py +0 -0
  283. {pycharter-0.0.19 → pycharter-0.0.22}/tests/test_pydantic_generator.py +0 -0
  284. {pycharter-0.0.19 → pycharter-0.0.22}/tests/test_refs_and_definitions.py +0 -0
  285. {pycharter-0.0.19 → pycharter-0.0.22}/tests/test_runtime_validator.py +0 -0
  286. {pycharter-0.0.19 → pycharter-0.0.22}/tests/test_schema_parser.py +0 -0
  287. {pycharter-0.0.19 → pycharter-0.0.22}/tests/test_value_injector.py +0 -0
  288. {pycharter-0.0.19 → pycharter-0.0.22}/tests/test_x_validators.py +0 -0
  289. {pycharter-0.0.19 → pycharter-0.0.22}/ui/__init__.py +0 -0
  290. {pycharter-0.0.19 → pycharter-0.0.22}/ui/build.py +0 -0
  291. {pycharter-0.0.19 → pycharter-0.0.22}/ui/dev.py +0 -0
  292. {pycharter-0.0.19 → pycharter-0.0.22}/ui/server.py +0 -0
  293. {pycharter-0.0.19 → pycharter-0.0.22}/ui/static/.gitkeep +0 -0
  294. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/404/index.html +0 -0
  295. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/404.html +0 -0
  296. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/__next.__PAGE__.txt +0 -0
  297. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/__next._full.txt +0 -0
  298. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/__next._head.txt +0 -0
  299. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/__next._index.txt +0 -0
  300. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/__next._tree.txt +0 -0
  301. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/_next/static/chunks/4e310fe5005770a3.css +0 -0
  302. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/_not-found/__next._full.txt +0 -0
  303. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/_not-found/__next._head.txt +0 -0
  304. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/_not-found/__next._index.txt +0 -0
  305. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/_not-found/__next._not-found.__PAGE__.txt +0 -0
  306. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/_not-found/__next._not-found.txt +0 -0
  307. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/_not-found/__next._tree.txt +0 -0
  308. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/_not-found/index.html +0 -0
  309. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/_not-found/index.txt +0 -0
  310. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/contracts/__next._full.txt +0 -0
  311. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/contracts/__next._head.txt +0 -0
  312. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/contracts/__next._index.txt +0 -0
  313. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/contracts/__next._tree.txt +0 -0
  314. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/contracts/__next.contracts.__PAGE__.txt +0 -0
  315. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/contracts/__next.contracts.txt +0 -0
  316. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/contracts/index.html +0 -0
  317. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/contracts/index.txt +0 -0
  318. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/documentation/__next._full.txt +0 -0
  319. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/documentation/__next._head.txt +0 -0
  320. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/documentation/__next._index.txt +0 -0
  321. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/documentation/__next._tree.txt +0 -0
  322. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/documentation/__next.documentation.__PAGE__.txt +0 -0
  323. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/documentation/__next.documentation.txt +0 -0
  324. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/documentation/index.html +0 -0
  325. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/documentation/index.txt +0 -0
  326. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/index.html +0 -0
  327. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/index.txt +0 -0
  328. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/metadata/__next._full.txt +0 -0
  329. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/metadata/__next._head.txt +0 -0
  330. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/metadata/__next._index.txt +0 -0
  331. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/metadata/__next._tree.txt +0 -0
  332. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/metadata/__next.metadata.__PAGE__.txt +0 -0
  333. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/metadata/__next.metadata.txt +0 -0
  334. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/metadata/index.html +0 -0
  335. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/metadata/index.txt +0 -0
  336. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/quality/__next._full.txt +0 -0
  337. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/quality/__next._head.txt +0 -0
  338. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/quality/__next._index.txt +0 -0
  339. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/quality/__next._tree.txt +0 -0
  340. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/quality/__next.quality.__PAGE__.txt +0 -0
  341. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/quality/__next.quality.txt +0 -0
  342. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/quality/index.html +0 -0
  343. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/quality/index.txt +0 -0
  344. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/rules/__next._full.txt +0 -0
  345. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/rules/__next._head.txt +0 -0
  346. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/rules/__next._index.txt +0 -0
  347. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/rules/__next._tree.txt +0 -0
  348. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/rules/__next.rules.__PAGE__.txt +0 -0
  349. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/rules/__next.rules.txt +0 -0
  350. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/rules/index.html +0 -0
  351. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/rules/index.txt +0 -0
  352. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/schemas/__next._full.txt +0 -0
  353. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/schemas/__next._head.txt +0 -0
  354. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/schemas/__next._index.txt +0 -0
  355. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/schemas/__next._tree.txt +0 -0
  356. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/schemas/__next.schemas.__PAGE__.txt +0 -0
  357. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/schemas/__next.schemas.txt +0 -0
  358. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/schemas/index.html +0 -0
  359. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/schemas/index.txt +0 -0
  360. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/settings/__next._full.txt +0 -0
  361. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/settings/__next._head.txt +0 -0
  362. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/settings/__next._index.txt +0 -0
  363. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/settings/__next._tree.txt +0 -0
  364. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/settings/__next.settings.__PAGE__.txt +0 -0
  365. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/settings/__next.settings.txt +0 -0
  366. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/settings/index.html +0 -0
  367. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/settings/index.txt +0 -0
  368. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/validation/__next._full.txt +0 -0
  369. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/validation/__next._head.txt +0 -0
  370. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/validation/__next._index.txt +0 -0
  371. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/validation/__next._tree.txt +0 -0
  372. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/validation/__next.validation.__PAGE__.txt +0 -0
  373. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/validation/__next.validation.txt +0 -0
  374. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/validation/index.html +0 -0
  375. {pycharter-0.0.19/ui → pycharter-0.0.22/ui/static}/static/validation/index.txt +0 -0
  376. {pycharter-0.0.19 → pycharter-0.0.22}/worker/__init__.py +0 -0
  377. {pycharter-0.0.19 → pycharter-0.0.22}/worker/cli.py +0 -0
  378. {pycharter-0.0.19 → pycharter-0.0.22}/worker/models.py +0 -0
  379. {pycharter-0.0.19 → pycharter-0.0.22}/worker/processor.py +0 -0
@@ -16,6 +16,11 @@ prune ui/.next
16
16
  prune ui/out
17
17
  prune ui/src
18
18
  prune ui/public
19
- recursive-exclude ui *.ts *.tsx *.js *.json *.md
19
+ # Exclude source files but NOT static build files
20
+ # Note: ui/static is explicitly included above, so these excludes won't affect it
21
+ recursive-exclude ui/src *.ts *.tsx *.js *.json *.md
22
+ recursive-exclude ui/src *.config.*
23
+ # Exclude other UI files (but not ui/static which is already included)
24
+ recursive-exclude ui *.ts *.tsx *.json *.md
20
25
  recursive-exclude ui *.config.*
21
26
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pycharter
3
- Version: 0.0.19
3
+ Version: 0.0.22
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"
@@ -158,12 +159,15 @@ pycharter ui dev # Development mode with hot reload
158
159
 
159
160
  ## 🚀 Quick Start
160
161
 
162
+ ### Quick Start: Convenience Functions (One-off Use)
163
+
161
164
  ```python
162
- from pycharter import from_dict
165
+ from pycharter import from_dict, validate
163
166
 
164
167
  # Define your JSON schema
165
168
  schema = {
166
169
  "type": "object",
170
+ "version": "1.0.0",
167
171
  "properties": {
168
172
  "name": {"type": "string"},
169
173
  "age": {"type": "integer"},
@@ -172,15 +176,91 @@ schema = {
172
176
  "required": ["name", "age"]
173
177
  }
174
178
 
175
- # Generate a Pydantic model
179
+ # Generate a Pydantic model (convenience function)
176
180
  Person = from_dict(schema, "Person")
177
181
 
178
- # Use it like any Pydantic model
179
- person = Person(name="Alice", age=30, email="alice@example.com")
180
- print(person.name) # Output: Alice
181
- print(person.age) # Output: 30
182
+ # Validate data
183
+ result = validate(Person, {"name": "Alice", "age": 30, "email": "alice@example.com"})
184
+ if result.is_valid:
185
+ print(f"Valid: {result.data.name}") # Output: Valid: Alice
186
+ ```
187
+
188
+ ### Production Use: Validator Class (Recommended)
189
+
190
+ For production code with multiple validations, use the `Validator` class for better performance:
191
+
192
+ ```python
193
+ from pycharter import Validator
194
+
195
+ # Create validator from contract directory or file
196
+ validator = Validator(contract_dir="data/contracts/user")
197
+ # Or: validator = Validator(contract_file="user_contract.yaml")
198
+
199
+ # Validate multiple records efficiently (model is cached)
200
+ result1 = validator.validate({"name": "Alice", "age": 30})
201
+ result2 = validator.validate({"name": "Bob", "age": 25})
202
+
203
+ # Batch validation
204
+ results = validator.validate_batch([data1, data2, data3])
182
205
  ```
183
206
 
207
+ ### With Metadata Store
208
+
209
+ ```python
210
+ from pycharter import Validator, SQLiteMetadataStore
211
+
212
+ # Connect to metadata store
213
+ store = SQLiteMetadataStore("metadata.db")
214
+ store.connect()
215
+
216
+ # Create validator from store
217
+ validator = Validator(store=store, schema_id="user_schema_v1")
218
+
219
+ # Validate data
220
+ result = validator.validate({"name": "Alice", "age": 30})
221
+ ```
222
+
223
+ ## 📐 API Organization
224
+
225
+ PyCharter's API is organized into **three tiers** to help you choose the right approach for your use case:
226
+
227
+ ### Tier 1: Primary Interfaces (⭐ Recommended for Production)
228
+
229
+ **Classes** that provide the best performance and most features:
230
+ - **`Validator`** - Primary validation interface (use for multiple validations)
231
+ - **`QualityCheck`** - Primary quality assurance interface
232
+ - **`MetadataStoreClient`** - Base class for metadata stores
233
+
234
+ **When to use**: Production code, batch processing, when you need to validate multiple records.
235
+
236
+ ### Tier 2: Convenience Functions (Quick Start)
237
+
238
+ **Functions** that make common tasks easy and discoverable:
239
+ - **Input helpers**: `from_dict()`, `from_file()`, `from_json()`, `from_url()`
240
+ - **Output helpers**: `to_dict()`, `to_file()`, `to_json()`
241
+ - **Validation helpers**: `validate_with_store()`, `validate_with_contract()`
242
+ - **Contract helpers**: `parse_contract_file()`, `build_contract()`
243
+
244
+ **When to use**: Quick scripts, one-off validations, exploratory work, learning the library.
245
+
246
+ ### Tier 3: Low-Level Utilities
247
+
248
+ **Functions** for when you already have models or need fine-grained control:
249
+ - **`validate()`** - Validate with existing Pydantic model
250
+ - **`validate_batch()`** - Batch validate with existing model
251
+ - **`model_to_schema()`** - Core conversion function
252
+
253
+ **When to use**: Advanced use cases, when you've already generated models, custom workflows.
254
+
255
+ ### Choosing the Right Approach
256
+
257
+ | Use Case | Recommended Approach | Example |
258
+ |----------|---------------------|---------|
259
+ | **Production pipeline with multiple validations** | `Validator` class | `validator = Validator(store=store, schema_id="schema"); validator.validate(data)` |
260
+ | **Quick one-off validation** | Convenience function | `validate_with_contract("contract.yaml", data)` |
261
+ | **You already have a model** | Low-level function | `validate(UserModel, data)` |
262
+ | **Batch processing** | `Validator.validate_batch()` | `validator.validate_batch([data1, data2, data3])` |
263
+
184
264
  ## 🏗️ Core Services & Data Production Journey
185
265
 
186
266
  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 +371,20 @@ result = validate_with_contract(contract, {"name": "Alice", "age": "30"})
291
371
 
292
372
  **Available Implementations**:
293
373
  - **PostgresMetadataStore** - For PostgreSQL databases (recommended for production)
374
+ - **SQLiteMetadataStore** - For SQLite databases (great for development and small deployments)
294
375
  - **MongoDBMetadataStore** - For MongoDB databases
295
376
  - **RedisMetadataStore** - For Redis databases
296
377
  - **InMemoryMetadataStore** - For testing and development (no persistence)
297
378
 
298
379
  **Example**:
299
380
  ```python
300
- from pycharter import PostgresMetadataStore, parse_contract_file
381
+ from pycharter import SQLiteMetadataStore, parse_contract_file
301
382
 
302
383
  # Parse contract
303
384
  metadata = parse_contract_file("contract.yaml")
304
385
 
305
- # Use PostgreSQL metadata store (or MongoDBMetadataStore, RedisMetadataStore, etc.)
306
- store = PostgresMetadataStore(connection_string="postgresql://user:pass@localhost:5432/pycharter")
386
+ # Use SQLite metadata store (or PostgresMetadataStore, MongoDBMetadataStore, RedisMetadataStore, etc.)
387
+ store = SQLiteMetadataStore("metadata.db")
307
388
  store.connect()
308
389
 
309
390
  # Store decomposed components
@@ -415,6 +496,24 @@ ProductModel = from_dict(schema, "Product") # Round-trip
415
496
 
416
497
  **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
498
 
499
+ **API Organization**:
500
+
501
+ PyCharter provides validation through three tiers:
502
+
503
+ 1. **Tier 1: Validator Class** (⭐ **PRIMARY INTERFACE** - Recommended for production)
504
+ - Best performance for multiple validations (model is cached)
505
+ - Supports all data sources (contract files, directories, stores, dictionaries)
506
+ - Reusable instance for batch processing
507
+
508
+ 2. **Tier 2: Convenience Functions** (Quick start - one-off validations)
509
+ - `validate_with_store()` - Quick validation with metadata store
510
+ - `validate_with_contract()` - Quick validation with contract file/dict
511
+ - `get_model_from_store()` / `get_model_from_contract()` - Get model for reuse
512
+
513
+ 3. **Tier 3: Low-Level Functions** (When you already have a model)
514
+ - `validate()` - Validate single record with existing model
515
+ - `validate_batch()` - Batch validate with existing model
516
+
418
517
  **How It Works**:
419
518
  - Takes a Pydantic model (generated from a schema) and raw data
420
519
  - Validates data against the model's constraints
@@ -422,55 +521,60 @@ ProductModel = from_dict(schema, "Product") # Round-trip
422
521
  - Supports single record and batch validation
423
522
  - Can be used in strict mode (raises exceptions) or lenient mode (returns results)
424
523
 
425
- **Two Validation Modes**:
524
+ **Example - Validator Class (Recommended)**:
525
+ ```python
526
+ from pycharter import Validator, SQLiteMetadataStore
426
527
 
427
- 1. **Database-Backed Validation** (with metadata store):
428
- - Retrieve schemas and rules from database
429
- - Use `validate_with_store()`, `validate_batch_with_store()`, `get_model_from_store()`
528
+ # Option 1: From contract directory (no database)
529
+ validator = Validator(contract_dir="data/contracts/user")
530
+ result = validator.validate({"name": "Alice", "age": 30})
430
531
 
431
- 2. **Contract-Based Validation** (no database required):
432
- - Validate directly against contract files or dictionaries
433
- - Use `validate_with_contract()`, `validate_batch_with_contract()`, `get_model_from_contract()`
532
+ # Option 2: From metadata store (with database)
533
+ store = SQLiteMetadataStore("metadata.db")
534
+ store.connect()
535
+ validator = Validator(store=store, schema_id="user_schema_v1")
536
+ result = validator.validate({"name": "Alice", "age": 30})
434
537
 
435
- **Example - Database-Backed**:
538
+ # Option 3: From contract file
539
+ validator = Validator(contract_file="user_contract.yaml")
540
+ result = validator.validate({"name": "Alice", "age": 30})
541
+
542
+ # Batch validation (efficient - model cached)
543
+ results = validator.validate_batch([data1, data2, data3])
544
+ ```
545
+
546
+ **Example - Convenience Functions (Quick Start)**:
436
547
  ```python
437
- from pycharter import validate_with_store, InMemoryMetadataStore
548
+ from pycharter import validate_with_store, validate_with_contract, SQLiteMetadataStore
438
549
 
439
- # Store and validate with database
440
- store = InMemoryMetadataStore()
550
+ # Quick validation with store
551
+ store = SQLiteMetadataStore("metadata.db")
441
552
  store.connect()
442
- # ... store schema, rules, etc. ...
443
-
444
- # Validate using store
445
553
  result = validate_with_store(store, "user_schema_v1", {"name": "Alice", "age": 30})
446
- if result.is_valid:
447
- print(f"Valid user: {result.data.name}")
554
+
555
+ # Quick validation with contract file (no database)
556
+ result = validate_with_contract("user_contract.yaml", {"name": "Alice", "age": 30})
448
557
  ```
449
558
 
450
- **Example - Contract-Based (No Database)**:
559
+ **Example - Low-Level (When You Have a Model)**:
451
560
  ```python
452
- from pycharter import validate_with_contract, get_model_from_contract, validate
561
+ from pycharter import from_dict, validate, validate_batch
453
562
 
454
- # Validate directly from contract file (simplest)
455
- result = validate_with_contract(
456
- "data/examples/book/book_contract.yaml",
457
- {"isbn": "1234567890", "title": "Book", ...}
458
- )
563
+ # Generate model
564
+ UserModel = from_dict(schema, "User")
459
565
 
460
- # Or get model once, validate multiple times (efficient)
461
- BookModel = get_model_from_contract("book_contract.yaml")
462
- result1 = validate(BookModel, data1)
463
- result2 = validate(BookModel, data2)
566
+ # Validate single record
567
+ result = validate(UserModel, {"name": "Alice", "age": 30})
464
568
 
465
- # Or from dictionary
466
- contract = {
467
- "schema": {"type": "object", "properties": {...}},
468
- "coercion_rules": {"rules": {...}},
469
- "validation_rules": {"rules": {...}}
470
- }
471
- result = validate_with_contract(contract, data)
569
+ # Batch validate
570
+ results = validate_batch(UserModel, [data1, data2, data3])
472
571
  ```
473
572
 
573
+ **Performance Tips**:
574
+ - ⚡ **For multiple validations**: Use `Validator` class (model is cached)
575
+ - ⚡ **For one-off validations**: Convenience functions are fine
576
+ - ⚡ **For batch processing**: Use `Validator.validate_batch()` or `validate_batch()`
577
+
474
578
  **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
579
 
476
580
  ---
@@ -533,9 +637,9 @@ Here's how all services work together in a complete data production journey:
533
637
  ```python
534
638
  from pycharter import (
535
639
  parse_contract_file,
536
- PostgresMetadataStore,
640
+ SQLiteMetadataStore,
537
641
  from_dict,
538
- validate,
642
+ Validator,
539
643
  to_dict
540
644
  )
541
645
 
@@ -543,7 +647,7 @@ from pycharter import (
543
647
  metadata = parse_contract_file("user_contract.yaml")
544
648
 
545
649
  # Step 2: Store metadata in database
546
- store = PostgresMetadataStore(connection_string="postgresql://user:pass@localhost:5432/pycharter")
650
+ store = SQLiteMetadataStore("metadata.db")
547
651
  store.connect()
548
652
  schema_id = store.store_schema("user", metadata.schema, version="1.0")
549
653
 
@@ -570,14 +674,27 @@ UserModel = from_dict(schema, "User")
570
674
  schema_doc = to_dict(UserModel)
571
675
 
572
676
  # Step 5: Validate data in production pipeline
677
+ # Option A: Using Validator class (recommended for production)
678
+ validator = Validator(store=store, schema_id=schema_id)
679
+
573
680
  def process_user_data(raw_data):
574
- result = validate(UserModel, raw_data)
681
+ result = validator.validate(raw_data)
575
682
  if result.is_valid:
576
683
  # Process validated data
577
684
  return result.data
578
685
  else:
579
686
  # Handle validation errors
580
687
  raise ValueError(f"Invalid data: {result.errors}")
688
+
689
+ # Option B: Using convenience function (quick start)
690
+ from pycharter import validate_with_store
691
+
692
+ def process_user_data_quick(raw_data):
693
+ result = validate_with_store(store, schema_id, raw_data)
694
+ if result.is_valid:
695
+ return result.data
696
+ else:
697
+ raise ValueError(f"Invalid data: {result.errors}")
581
698
  ```
582
699
 
583
700
  ---
@@ -646,12 +763,14 @@ Each service is designed to be **independent** yet **composable**, allowing you
646
763
 
647
764
  ### Basic Usage
648
765
 
766
+ **Using Convenience Functions** (Quick Start):
649
767
  ```python
650
768
  from pycharter import from_dict, from_json, from_file
651
769
 
652
770
  # From dictionary
653
771
  schema = {
654
772
  "type": "object",
773
+ "version": "1.0.0",
655
774
  "properties": {
656
775
  "title": {"type": "string"},
657
776
  "published": {"type": "boolean", "default": False}
@@ -660,13 +779,26 @@ schema = {
660
779
  Article = from_dict(schema, "Article")
661
780
 
662
781
  # From JSON string
663
- schema_json = '{"type": "object", "properties": {"name": {"type": "string"}}}'
782
+ schema_json = '{"type": "object", "version": "1.0.0", "properties": {"name": {"type": "string"}}}'
664
783
  User = from_json(schema_json, "User")
665
784
 
666
785
  # From file
667
786
  Product = from_file("product_schema.json", "Product")
668
787
  ```
669
788
 
789
+ **Using Validator Class** (Production):
790
+ ```python
791
+ from pycharter import Validator
792
+
793
+ # From contract directory
794
+ validator = Validator(contract_dir="data/contracts/article")
795
+ result = validator.validate({"title": "My Article", "published": True})
796
+
797
+ # From contract file
798
+ validator = Validator(contract_file="article_contract.yaml")
799
+ result = validator.validate({"title": "My Article", "published": True})
800
+ ```
801
+
670
802
  ### Nested Objects
671
803
 
672
804
  ```python
@@ -674,6 +806,7 @@ from pycharter import from_dict
674
806
 
675
807
  schema = {
676
808
  "type": "object",
809
+ "version": "1.0.0",
677
810
  "properties": {
678
811
  "name": {"type": "string"},
679
812
  "address": {
@@ -707,6 +840,7 @@ from pycharter import from_dict
707
840
 
708
841
  schema = {
709
842
  "type": "object",
843
+ "version": "1.0.0",
710
844
  "properties": {
711
845
  "tags": {
712
846
  "type": "array",
@@ -739,13 +873,14 @@ print(cart.items[0].name) # Output: Apple
739
873
 
740
874
  ### Coercion and Validation
741
875
 
742
- Charter supports **coercion** (pre-validation transformation) and **validation** (post-validation checks):
876
+ PyCharter supports **coercion** (pre-validation transformation) and **validation** (post-validation checks):
743
877
 
744
878
  ```python
745
879
  from pycharter import from_dict
746
880
 
747
881
  schema = {
748
882
  "type": "object",
883
+ "version": "1.0.0",
749
884
  "properties": {
750
885
  "flight_number": {
751
886
  "type": "integer",
@@ -871,13 +1006,88 @@ register_validation("must_be_positive", must_be_positive)
871
1006
 
872
1007
  ## 📖 API Reference
873
1008
 
874
- ### Main Functions
1009
+ PyCharter's API is organized into three tiers to help you choose the right approach:
875
1010
 
1011
+ ### Tier 1: Primary Interfaces (Classes - Best Performance)
1012
+
1013
+ **Validator** - Primary validation interface (recommended for production)
1014
+ ```python
1015
+ from pycharter import Validator
1016
+
1017
+ # Create validator from various sources
1018
+ validator = Validator(contract_dir="data/contracts/user")
1019
+ validator = Validator(contract_file="contract.yaml")
1020
+ validator = Validator(store=store, schema_id="user_schema")
1021
+ validator = Validator(contract_dict={...})
1022
+
1023
+ # Validate data
1024
+ result = validator.validate(data)
1025
+ results = validator.validate_batch([data1, data2])
1026
+ model = validator.get_model() # Get the generated Pydantic model
1027
+ ```
1028
+
1029
+ **QualityCheck** - Primary quality assurance interface
1030
+ ```python
1031
+ from pycharter import QualityCheck, QualityCheckOptions
1032
+
1033
+ check = QualityCheck(store=store)
1034
+ report = check.run(schema_id="user_schema", data=data, options=QualityCheckOptions(...))
1035
+ ```
1036
+
1037
+ **MetadataStoreClient** - Base class for metadata stores
1038
+ ```python
1039
+ from pycharter import MetadataStoreClient, SQLiteMetadataStore, PostgresMetadataStore
1040
+
1041
+ store = SQLiteMetadataStore("metadata.db")
1042
+ store.connect()
1043
+ ```
1044
+
1045
+ ### Tier 2: Convenience Functions (Quick Start)
1046
+
1047
+ **Pydantic Generator** - Input type helpers
876
1048
  - **`from_dict(schema: dict, model_name: str = "DynamicModel")`** - Create model from dictionary
877
1049
  - **`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 file
1050
+ - **`from_file(file_path: str, model_name: str = None)`** - Create model from file (JSON/YAML)
879
1051
  - **`from_url(url: str, model_name: str = "DynamicModel")`** - Create model from URL
880
- - **`schema_to_model(schema: dict, model_name: str = "DynamicModel")`** - Low-level model generator
1052
+ - **`generate_model(schema: dict, model_name: str = "DynamicModel")`** - Advanced: more control
1053
+ - **`generate_model_file(schema: dict, output_path: str, model_name: str = "DynamicModel")`** - Generate and save to file
1054
+
1055
+ **JSON Schema Converter** - Output type helpers
1056
+ - **`to_dict(model: Type[BaseModel], ...)`** - Convert model to JSON Schema dictionary
1057
+ - **`to_file(model: Type[BaseModel], file_path: str, ...)`** - Convert model to file
1058
+ - **`to_json(model: Type[BaseModel], ...)`** - Convert model to JSON string
1059
+ - **`model_to_schema(model: Type[BaseModel], ...)`** - Advanced: core conversion function
1060
+
1061
+ **Runtime Validator** - Data source helpers
1062
+ - **`validate_with_store(store, schema_id, data, ...)`** - Quick validation with metadata store
1063
+ - **`validate_batch_with_store(store, schema_id, data_list, ...)`** - Batch validation with store
1064
+ - **`validate_with_contract(contract, data, ...)`** - Quick validation with contract file/dict
1065
+ - **`validate_batch_with_contract(contract, data_list, ...)`** - Batch validation with contract
1066
+ - **`get_model_from_store(store, schema_id, ...)`** - Get model from metadata store
1067
+ - **`get_model_from_contract(contract, ...)`** - Get model from contract
1068
+ - **`validate_input(contract, ...)`** - Decorator for function input validation
1069
+ - **`validate_output(contract, ...)`** - Decorator for function output validation
1070
+ - **`validate_with_contract_decorator(contract, ...)`** - Decorator for contract-based validation
1071
+
1072
+ **Contract Management**
1073
+ - **`parse_contract(contract_dict: dict)`** - Parse contract dictionary
1074
+ - **`parse_contract_file(file_path: str)`** - Parse contract file (YAML/JSON)
1075
+ - **`build_contract(artifacts: ContractArtifacts)`** - Build contract from artifacts
1076
+ - **`build_contract_from_store(store, schema_id, ...)`** - Build contract from metadata store
1077
+
1078
+ ### Tier 3: Low-Level Utilities (When You Have Models)
1079
+
1080
+ - **`validate(model: Type[BaseModel], data: dict, strict: bool = False)`** - Validate single record
1081
+ - **`validate_batch(model: Type[BaseModel], data_list: List[dict], strict: bool = False)`** - Batch validate
1082
+ - **`ValidationResult`** - Result class with `is_valid`, `data`, and `errors` attributes
1083
+
1084
+ ### Metadata Store Implementations
1085
+
1086
+ - **`InMemoryMetadataStore()`** - In-memory store (testing/development)
1087
+ - **`SQLiteMetadataStore(database_path: str)`** - SQLite database
1088
+ - **`PostgresMetadataStore(connection_string: str)`** - PostgreSQL database
1089
+ - **`MongoDBMetadataStore(connection_string: str)`** - MongoDB database
1090
+ - **`RedisMetadataStore(connection_string: str)`** - Redis database
881
1091
 
882
1092
  ## 🎯 Design Principles & Requirements
883
1093
 
@@ -979,21 +1189,33 @@ pytest -k "coercion"
979
1189
 
980
1190
  ## 📦 Publishing to PyPI
981
1191
 
1192
+ **Automatic publishing via GitHub Releases (Trusted Publishing - no tokens needed!):**
1193
+
982
1194
  ```bash
983
- # Update version in pyproject.toml
984
- # Clean previous builds
985
- make clean
1195
+ # 1. Update version in pyproject.toml
1196
+ # version = "0.0.21"
1197
+
1198
+ # 2. Commit and push
1199
+ git add pyproject.toml
1200
+ git commit -m "Bump version to 0.0.21"
1201
+ git push
986
1202
 
987
- # Build package
988
- make build
1203
+ # 3. Create GitHub Release (automatically publishes to PyPI)
1204
+ gh release create v0.0.21 --title "v0.0.21" --notes "Release notes"
1205
+ ```
989
1206
 
990
- # Test on TestPyPI
991
- make publish-test
1207
+ The workflow automatically:
1208
+ - ✅ Builds UI
1209
+ - ✅ Builds Python package
1210
+ - ✅ Publishes to PyPI (using Trusted Publishing)
992
1211
 
993
- # Publish to PyPI
994
- make publish
1212
+ **Local build:**
1213
+ ```bash
1214
+ make build # Builds package (UI built automatically via setup.py)
995
1215
  ```
996
1216
 
1217
+ See `PUBLISHING.md` for complete documentation.
1218
+
997
1219
  ## 📋 JSON Schema Compliance
998
1220
 
999
1221
  PyCharter is fully compliant with **JSON Schema Draft 2020-12** standard: