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.
Files changed (520) hide show
  1. {pycharter-0.0.20 → pycharter-0.0.23}/MANIFEST.in +2 -0
  2. {pycharter-0.0.20/pycharter.egg-info → pycharter-0.0.23}/PKG-INFO +289 -62
  3. {pycharter-0.0.20 → pycharter-0.0.23}/README.md +282 -61
  4. {pycharter-0.0.20 → pycharter-0.0.23}/api/dependencies/__init__.py +2 -1
  5. {pycharter-0.0.20 → pycharter-0.0.23}/api/dependencies/database.py +71 -5
  6. {pycharter-0.0.20 → pycharter-0.0.23}/api/main.py +47 -8
  7. {pycharter-0.0.20 → pycharter-0.0.23}/api/models/contracts.py +6 -4
  8. {pycharter-0.0.20 → pycharter-0.0.23}/api/models/metadata.py +11 -7
  9. {pycharter-0.0.20 → pycharter-0.0.23}/api/models/schemas.py +16 -10
  10. {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/contracts.py +498 -226
  11. {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/metadata.py +52 -211
  12. {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/schemas.py +1 -1
  13. {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/settings.py +88 -1
  14. {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/templates.py +43 -24
  15. pycharter-0.0.23/api/utils.py +224 -0
  16. pycharter-0.0.23/pycharter/__init__.py +211 -0
  17. pycharter-0.0.23/pycharter/data/templates/etl/README.md +91 -0
  18. pycharter-0.0.23/pycharter/data/templates/etl/extract_cloud_azure.yaml +23 -0
  19. pycharter-0.0.23/pycharter/data/templates/etl/extract_cloud_gcs.yaml +22 -0
  20. pycharter-0.0.23/pycharter/data/templates/etl/extract_cloud_s3.yaml +24 -0
  21. pycharter-0.0.23/pycharter/data/templates/etl/extract_database.yaml +28 -0
  22. pycharter-0.0.23/pycharter/data/templates/etl/extract_database_ssh.yaml +27 -0
  23. pycharter-0.0.23/pycharter/data/templates/etl/extract_file_csv.yaml +17 -0
  24. pycharter-0.0.23/pycharter/data/templates/etl/extract_file_glob.yaml +17 -0
  25. pycharter-0.0.23/pycharter/data/templates/etl/extract_file_json.yaml +14 -0
  26. pycharter-0.0.23/pycharter/data/templates/etl/extract_file_parquet.yaml +13 -0
  27. pycharter-0.0.23/pycharter/data/templates/etl/extract_http_paginated.yaml +75 -0
  28. pycharter-0.0.23/pycharter/data/templates/etl/extract_http_path_params.yaml +45 -0
  29. pycharter-0.0.23/pycharter/data/templates/etl/extract_http_simple.yaml +52 -0
  30. pycharter-0.0.23/pycharter/data/templates/etl/load_insert.yaml +17 -0
  31. pycharter-0.0.23/pycharter/data/templates/etl/load_postgresql.yaml +17 -0
  32. pycharter-0.0.23/pycharter/data/templates/etl/load_sqlite.yaml +16 -0
  33. pycharter-0.0.23/pycharter/data/templates/etl/load_truncate_and_load.yaml +18 -0
  34. pycharter-0.0.23/pycharter/data/templates/etl/load_upsert.yaml +28 -0
  35. pycharter-0.0.23/pycharter/data/templates/etl/load_with_dlq.yaml +24 -0
  36. pycharter-0.0.23/pycharter/data/templates/etl/load_with_ssh_tunnel.yaml +28 -0
  37. pycharter-0.0.23/pycharter/data/templates/etl/pipeline_http_to_db.yaml +38 -0
  38. pycharter-0.0.23/pycharter/data/templates/etl/transform_combined.yaml +38 -0
  39. pycharter-0.0.23/pycharter/data/templates/etl/transform_custom_function.yaml +18 -0
  40. pycharter-0.0.23/pycharter/data/templates/etl/transform_jsonata.yaml +20 -0
  41. pycharter-0.0.23/pycharter/data/templates/etl/transform_simple.yaml +41 -0
  42. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/base.py +1 -2
  43. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/extraction.py +47 -262
  44. pycharter-0.0.23/pycharter/etl_generator/extractors/__init__.py +26 -0
  45. pycharter-0.0.23/pycharter/etl_generator/extractors/base.py +70 -0
  46. pycharter-0.0.23/pycharter/etl_generator/extractors/cloud_storage.py +454 -0
  47. pycharter-0.0.23/pycharter/etl_generator/extractors/database.py +151 -0
  48. pycharter-0.0.23/pycharter/etl_generator/extractors/factory.py +141 -0
  49. pycharter-0.0.23/pycharter/etl_generator/extractors/file.py +418 -0
  50. pycharter-0.0.23/pycharter/etl_generator/extractors/http.py +816 -0
  51. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/orchestrator.py +463 -487
  52. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/metadata_store/postgres.py +16 -191
  53. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/metadata_store/sqlite.py +12 -41
  54. {pycharter-0.0.20 → pycharter-0.0.23/pycharter.egg-info}/PKG-INFO +289 -62
  55. pycharter-0.0.23/pycharter.egg-info/SOURCES.txt +516 -0
  56. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter.egg-info/requires.txt +6 -0
  57. {pycharter-0.0.20 → pycharter-0.0.23}/pyproject.toml +14 -3
  58. pycharter-0.0.23/tests/test_extractors.py +279 -0
  59. pycharter-0.0.23/ui/static/404/index.html +1 -0
  60. pycharter-0.0.23/ui/static/404.html +1 -0
  61. pycharter-0.0.23/ui/static/__next.__PAGE__.txt +10 -0
  62. pycharter-0.0.23/ui/static/__next._full.txt +30 -0
  63. pycharter-0.0.23/ui/static/__next._head.txt +7 -0
  64. pycharter-0.0.23/ui/static/__next._index.txt +9 -0
  65. pycharter-0.0.23/ui/static/__next._tree.txt +2 -0
  66. pycharter-0.0.23/ui/static/_next/static/chunks/13d4a0fbd74c1ee4.js +1 -0
  67. pycharter-0.0.23/ui/static/_next/static/chunks/26dfc590f7714c03.js +1 -0
  68. pycharter-0.0.23/ui/static/_next/static/chunks/2edb43b48432ac04.js +441 -0
  69. pycharter-0.0.23/ui/static/_next/static/chunks/34d289e6db2ef551.js +1 -0
  70. pycharter-0.0.23/ui/static/_next/static/chunks/99508d9d5869cc27.js +1 -0
  71. pycharter-0.0.23/ui/static/_next/static/chunks/b313c35a6ba76574.js +1 -0
  72. pycharter-0.0.23/ui/static/_next/static/chunks/d2363397e1b2bcab.css +1 -0
  73. pycharter-0.0.23/ui/static/_next/static/chunks/f7d1a90dd75d2572.js +1 -0
  74. pycharter-0.0.23/ui/static/_not-found/__next._full.txt +17 -0
  75. pycharter-0.0.23/ui/static/_not-found/__next._head.txt +7 -0
  76. pycharter-0.0.23/ui/static/_not-found/__next._index.txt +9 -0
  77. pycharter-0.0.23/ui/static/_not-found/__next._not-found.__PAGE__.txt +5 -0
  78. pycharter-0.0.23/ui/static/_not-found/__next._not-found.txt +4 -0
  79. pycharter-0.0.23/ui/static/_not-found/__next._tree.txt +2 -0
  80. pycharter-0.0.23/ui/static/_not-found/index.html +1 -0
  81. pycharter-0.0.23/ui/static/_not-found/index.txt +17 -0
  82. pycharter-0.0.23/ui/static/contracts/__next._full.txt +21 -0
  83. pycharter-0.0.23/ui/static/contracts/__next._head.txt +7 -0
  84. pycharter-0.0.23/ui/static/contracts/__next._index.txt +9 -0
  85. pycharter-0.0.23/ui/static/contracts/__next._tree.txt +2 -0
  86. pycharter-0.0.23/ui/static/contracts/__next.contracts.__PAGE__.txt +9 -0
  87. pycharter-0.0.23/ui/static/contracts/__next.contracts.txt +4 -0
  88. pycharter-0.0.23/ui/static/contracts/index.html +1 -0
  89. pycharter-0.0.23/ui/static/contracts/index.txt +21 -0
  90. pycharter-0.0.23/ui/static/documentation/__next._full.txt +21 -0
  91. pycharter-0.0.23/ui/static/documentation/__next._head.txt +7 -0
  92. pycharter-0.0.23/ui/static/documentation/__next._index.txt +9 -0
  93. pycharter-0.0.23/ui/static/documentation/__next._tree.txt +2 -0
  94. pycharter-0.0.23/ui/static/documentation/__next.documentation.__PAGE__.txt +9 -0
  95. pycharter-0.0.23/ui/static/documentation/__next.documentation.txt +4 -0
  96. pycharter-0.0.23/ui/static/documentation/index.html +93 -0
  97. pycharter-0.0.23/ui/static/documentation/index.txt +21 -0
  98. pycharter-0.0.23/ui/static/index.html +1 -0
  99. pycharter-0.0.23/ui/static/index.txt +30 -0
  100. pycharter-0.0.23/ui/static/metadata/__next._full.txt +21 -0
  101. pycharter-0.0.23/ui/static/metadata/__next._head.txt +7 -0
  102. pycharter-0.0.23/ui/static/metadata/__next._index.txt +9 -0
  103. pycharter-0.0.23/ui/static/metadata/__next._tree.txt +2 -0
  104. pycharter-0.0.23/ui/static/metadata/__next.metadata.__PAGE__.txt +9 -0
  105. pycharter-0.0.23/ui/static/metadata/__next.metadata.txt +4 -0
  106. pycharter-0.0.23/ui/static/metadata/index.html +1 -0
  107. pycharter-0.0.23/ui/static/metadata/index.txt +21 -0
  108. pycharter-0.0.23/ui/static/quality/__next._full.txt +21 -0
  109. pycharter-0.0.23/ui/static/quality/__next._head.txt +7 -0
  110. pycharter-0.0.23/ui/static/quality/__next._index.txt +9 -0
  111. pycharter-0.0.23/ui/static/quality/__next._tree.txt +2 -0
  112. pycharter-0.0.23/ui/static/quality/__next.quality.__PAGE__.txt +9 -0
  113. pycharter-0.0.23/ui/static/quality/__next.quality.txt +4 -0
  114. pycharter-0.0.23/ui/static/quality/index.html +2 -0
  115. pycharter-0.0.23/ui/static/quality/index.txt +21 -0
  116. pycharter-0.0.23/ui/static/rules/__next._full.txt +21 -0
  117. pycharter-0.0.23/ui/static/rules/__next._head.txt +7 -0
  118. pycharter-0.0.23/ui/static/rules/__next._index.txt +9 -0
  119. pycharter-0.0.23/ui/static/rules/__next._tree.txt +2 -0
  120. pycharter-0.0.23/ui/static/rules/__next.rules.__PAGE__.txt +9 -0
  121. pycharter-0.0.23/ui/static/rules/__next.rules.txt +4 -0
  122. pycharter-0.0.23/ui/static/rules/index.html +1 -0
  123. pycharter-0.0.23/ui/static/rules/index.txt +21 -0
  124. pycharter-0.0.23/ui/static/schemas/__next._full.txt +21 -0
  125. pycharter-0.0.23/ui/static/schemas/__next._head.txt +7 -0
  126. pycharter-0.0.23/ui/static/schemas/__next._index.txt +9 -0
  127. pycharter-0.0.23/ui/static/schemas/__next._tree.txt +2 -0
  128. pycharter-0.0.23/ui/static/schemas/__next.schemas.__PAGE__.txt +9 -0
  129. pycharter-0.0.23/ui/static/schemas/__next.schemas.txt +4 -0
  130. pycharter-0.0.23/ui/static/schemas/index.html +1 -0
  131. pycharter-0.0.23/ui/static/schemas/index.txt +21 -0
  132. pycharter-0.0.23/ui/static/settings/__next._full.txt +21 -0
  133. pycharter-0.0.23/ui/static/settings/__next._head.txt +7 -0
  134. pycharter-0.0.23/ui/static/settings/__next._index.txt +9 -0
  135. pycharter-0.0.23/ui/static/settings/__next._tree.txt +2 -0
  136. pycharter-0.0.23/ui/static/settings/__next.settings.__PAGE__.txt +9 -0
  137. pycharter-0.0.23/ui/static/settings/__next.settings.txt +4 -0
  138. pycharter-0.0.23/ui/static/settings/index.html +1 -0
  139. pycharter-0.0.23/ui/static/settings/index.txt +21 -0
  140. pycharter-0.0.23/ui/static/static/.gitkeep +0 -0
  141. pycharter-0.0.23/ui/static/static/404/index.html +1 -0
  142. pycharter-0.0.23/ui/static/static/404.html +1 -0
  143. pycharter-0.0.23/ui/static/static/__next.__PAGE__.txt +10 -0
  144. pycharter-0.0.23/ui/static/static/__next._full.txt +30 -0
  145. pycharter-0.0.23/ui/static/static/__next._head.txt +7 -0
  146. pycharter-0.0.23/ui/static/static/__next._index.txt +9 -0
  147. pycharter-0.0.23/ui/static/static/__next._tree.txt +2 -0
  148. pycharter-0.0.23/ui/static/static/_next/static/0rYA78L88aUyD2Uh38hhX/_buildManifest.js +11 -0
  149. pycharter-0.0.23/ui/static/static/_next/static/0rYA78L88aUyD2Uh38hhX/_ssgManifest.js +1 -0
  150. pycharter-0.0.23/ui/static/static/_next/static/chunks/13d4a0fbd74c1ee4.js +1 -0
  151. pycharter-0.0.23/ui/static/static/_next/static/chunks/222442f6da32302a.js +1 -0
  152. pycharter-0.0.23/ui/static/static/_next/static/chunks/247eb132b7f7b574.js +1 -0
  153. pycharter-0.0.23/ui/static/static/_next/static/chunks/297d55555b71baba.js +1 -0
  154. pycharter-0.0.23/ui/static/static/_next/static/chunks/2ab439ce003cd691.js +1 -0
  155. pycharter-0.0.23/ui/static/static/_next/static/chunks/2edb43b48432ac04.js +441 -0
  156. pycharter-0.0.23/ui/static/static/_next/static/chunks/414e77373f8ff61c.js +1 -0
  157. pycharter-0.0.23/ui/static/static/_next/static/chunks/49ca65abd26ae49e.js +1 -0
  158. pycharter-0.0.23/ui/static/static/_next/static/chunks/652ad0aa26265c47.js +2 -0
  159. pycharter-0.0.23/ui/static/static/_next/static/chunks/9667e7a3d359eb39.js +1 -0
  160. pycharter-0.0.23/ui/static/static/_next/static/chunks/9c23f44fff36548a.js +1 -0
  161. pycharter-0.0.23/ui/static/static/_next/static/chunks/a6dad97d9634a72d.js +1 -0
  162. pycharter-0.0.23/ui/static/static/_next/static/chunks/b32a0963684b9933.js +4 -0
  163. pycharter-0.0.23/ui/static/static/_next/static/chunks/c4fa4f4114b7c352.js +1 -0
  164. pycharter-0.0.23/ui/static/static/_next/static/chunks/c69f6cba366bd988.js +1 -0
  165. pycharter-0.0.23/ui/static/static/_next/static/chunks/d2363397e1b2bcab.css +1 -0
  166. pycharter-0.0.23/ui/static/static/_next/static/chunks/db913959c675cea6.js +1 -0
  167. pycharter-0.0.23/ui/static/static/_next/static/chunks/f061a4be97bfc3b3.js +1 -0
  168. pycharter-0.0.23/ui/static/static/_next/static/chunks/f2e7afeab1178138.js +1 -0
  169. pycharter-0.0.23/ui/static/static/_next/static/chunks/f7d1a90dd75d2572.js +1 -0
  170. pycharter-0.0.23/ui/static/static/_next/static/chunks/ff1a16fafef87110.js +1 -0
  171. pycharter-0.0.23/ui/static/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +3 -0
  172. pycharter-0.0.23/ui/static/static/_not-found/__next._full.txt +17 -0
  173. pycharter-0.0.23/ui/static/static/_not-found/__next._head.txt +7 -0
  174. pycharter-0.0.23/ui/static/static/_not-found/__next._index.txt +9 -0
  175. pycharter-0.0.23/ui/static/static/_not-found/__next._not-found.__PAGE__.txt +5 -0
  176. pycharter-0.0.23/ui/static/static/_not-found/__next._not-found.txt +4 -0
  177. pycharter-0.0.23/ui/static/static/_not-found/__next._tree.txt +2 -0
  178. pycharter-0.0.23/ui/static/static/_not-found/index.html +1 -0
  179. pycharter-0.0.23/ui/static/static/_not-found/index.txt +17 -0
  180. pycharter-0.0.23/ui/static/static/contracts/__next._full.txt +21 -0
  181. pycharter-0.0.23/ui/static/static/contracts/__next._head.txt +7 -0
  182. pycharter-0.0.23/ui/static/static/contracts/__next._index.txt +9 -0
  183. pycharter-0.0.23/ui/static/static/contracts/__next._tree.txt +2 -0
  184. pycharter-0.0.23/ui/static/static/contracts/__next.contracts.__PAGE__.txt +9 -0
  185. pycharter-0.0.23/ui/static/static/contracts/__next.contracts.txt +4 -0
  186. pycharter-0.0.23/ui/static/static/contracts/index.html +1 -0
  187. pycharter-0.0.23/ui/static/static/contracts/index.txt +21 -0
  188. pycharter-0.0.23/ui/static/static/documentation/__next._full.txt +21 -0
  189. pycharter-0.0.23/ui/static/static/documentation/__next._head.txt +7 -0
  190. pycharter-0.0.23/ui/static/static/documentation/__next._index.txt +9 -0
  191. pycharter-0.0.23/ui/static/static/documentation/__next._tree.txt +2 -0
  192. pycharter-0.0.23/ui/static/static/documentation/__next.documentation.__PAGE__.txt +9 -0
  193. pycharter-0.0.23/ui/static/static/documentation/__next.documentation.txt +4 -0
  194. pycharter-0.0.23/ui/static/static/documentation/index.html +93 -0
  195. pycharter-0.0.23/ui/static/static/documentation/index.txt +21 -0
  196. pycharter-0.0.23/ui/static/static/index.html +1 -0
  197. pycharter-0.0.23/ui/static/static/index.txt +30 -0
  198. pycharter-0.0.23/ui/static/static/metadata/__next._full.txt +21 -0
  199. pycharter-0.0.23/ui/static/static/metadata/__next._head.txt +7 -0
  200. pycharter-0.0.23/ui/static/static/metadata/__next._index.txt +9 -0
  201. pycharter-0.0.23/ui/static/static/metadata/__next._tree.txt +2 -0
  202. pycharter-0.0.23/ui/static/static/metadata/__next.metadata.__PAGE__.txt +9 -0
  203. pycharter-0.0.23/ui/static/static/metadata/__next.metadata.txt +4 -0
  204. pycharter-0.0.23/ui/static/static/metadata/index.html +1 -0
  205. pycharter-0.0.23/ui/static/static/metadata/index.txt +21 -0
  206. pycharter-0.0.23/ui/static/static/quality/__next._full.txt +21 -0
  207. pycharter-0.0.23/ui/static/static/quality/__next._head.txt +7 -0
  208. pycharter-0.0.23/ui/static/static/quality/__next._index.txt +9 -0
  209. pycharter-0.0.23/ui/static/static/quality/__next._tree.txt +2 -0
  210. pycharter-0.0.23/ui/static/static/quality/__next.quality.__PAGE__.txt +9 -0
  211. pycharter-0.0.23/ui/static/static/quality/__next.quality.txt +4 -0
  212. pycharter-0.0.23/ui/static/static/quality/index.html +2 -0
  213. pycharter-0.0.23/ui/static/static/quality/index.txt +21 -0
  214. pycharter-0.0.23/ui/static/static/rules/__next._full.txt +21 -0
  215. pycharter-0.0.23/ui/static/static/rules/__next._head.txt +7 -0
  216. pycharter-0.0.23/ui/static/static/rules/__next._index.txt +9 -0
  217. pycharter-0.0.23/ui/static/static/rules/__next._tree.txt +2 -0
  218. pycharter-0.0.23/ui/static/static/rules/__next.rules.__PAGE__.txt +9 -0
  219. pycharter-0.0.23/ui/static/static/rules/__next.rules.txt +4 -0
  220. pycharter-0.0.23/ui/static/static/rules/index.html +1 -0
  221. pycharter-0.0.23/ui/static/static/rules/index.txt +21 -0
  222. pycharter-0.0.23/ui/static/static/schemas/__next._full.txt +21 -0
  223. pycharter-0.0.23/ui/static/static/schemas/__next._head.txt +7 -0
  224. pycharter-0.0.23/ui/static/static/schemas/__next._index.txt +9 -0
  225. pycharter-0.0.23/ui/static/static/schemas/__next._tree.txt +2 -0
  226. pycharter-0.0.23/ui/static/static/schemas/__next.schemas.__PAGE__.txt +9 -0
  227. pycharter-0.0.23/ui/static/static/schemas/__next.schemas.txt +4 -0
  228. pycharter-0.0.23/ui/static/static/schemas/index.html +1 -0
  229. pycharter-0.0.23/ui/static/static/schemas/index.txt +21 -0
  230. pycharter-0.0.23/ui/static/static/settings/__next._full.txt +21 -0
  231. pycharter-0.0.23/ui/static/static/settings/__next._head.txt +7 -0
  232. pycharter-0.0.23/ui/static/static/settings/__next._index.txt +9 -0
  233. pycharter-0.0.23/ui/static/static/settings/__next._tree.txt +2 -0
  234. pycharter-0.0.23/ui/static/static/settings/__next.settings.__PAGE__.txt +9 -0
  235. pycharter-0.0.23/ui/static/static/settings/__next.settings.txt +4 -0
  236. pycharter-0.0.23/ui/static/static/settings/index.html +1 -0
  237. pycharter-0.0.23/ui/static/static/settings/index.txt +21 -0
  238. pycharter-0.0.23/ui/static/static/static/.gitkeep +0 -0
  239. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/222442f6da32302a.js +1 -0
  240. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/247eb132b7f7b574.js +1 -0
  241. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/297d55555b71baba.js +1 -0
  242. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/2ab439ce003cd691.js +1 -0
  243. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/414e77373f8ff61c.js +1 -0
  244. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/49ca65abd26ae49e.js +1 -0
  245. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/5e04d10c4a7b58a3.js +1 -0
  246. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/652ad0aa26265c47.js +2 -0
  247. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/75d88a058d8ffaa6.js +1 -0
  248. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/8c89634cf6bad76f.js +1 -0
  249. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/9667e7a3d359eb39.js +1 -0
  250. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/9c23f44fff36548a.js +1 -0
  251. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/a6dad97d9634a72d.js +1 -0
  252. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/b32a0963684b9933.js +4 -0
  253. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/c69f6cba366bd988.js +1 -0
  254. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/db913959c675cea6.js +1 -0
  255. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/f061a4be97bfc3b3.js +1 -0
  256. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/f2e7afeab1178138.js +1 -0
  257. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/ff1a16fafef87110.js +1 -0
  258. pycharter-0.0.23/ui/static/static/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +3 -0
  259. pycharter-0.0.23/ui/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_buildManifest.js +11 -0
  260. pycharter-0.0.23/ui/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_ssgManifest.js +1 -0
  261. pycharter-0.0.23/ui/static/static/validation/__next._full.txt +21 -0
  262. pycharter-0.0.23/ui/static/static/validation/__next._head.txt +7 -0
  263. pycharter-0.0.23/ui/static/static/validation/__next._index.txt +9 -0
  264. pycharter-0.0.23/ui/static/static/validation/__next._tree.txt +2 -0
  265. pycharter-0.0.23/ui/static/static/validation/__next.validation.__PAGE__.txt +9 -0
  266. pycharter-0.0.23/ui/static/static/validation/__next.validation.txt +4 -0
  267. pycharter-0.0.23/ui/static/static/validation/index.html +1 -0
  268. pycharter-0.0.23/ui/static/static/validation/index.txt +21 -0
  269. pycharter-0.0.23/ui/static/validation/__next._full.txt +21 -0
  270. pycharter-0.0.23/ui/static/validation/__next._head.txt +7 -0
  271. pycharter-0.0.23/ui/static/validation/__next._index.txt +9 -0
  272. pycharter-0.0.23/ui/static/validation/__next._tree.txt +2 -0
  273. pycharter-0.0.23/ui/static/validation/__next.validation.__PAGE__.txt +9 -0
  274. pycharter-0.0.23/ui/static/validation/__next.validation.txt +4 -0
  275. pycharter-0.0.23/ui/static/validation/index.html +1 -0
  276. pycharter-0.0.23/ui/static/validation/index.txt +21 -0
  277. pycharter-0.0.20/pycharter/__init__.py +0 -155
  278. pycharter-0.0.20/pycharter.egg-info/SOURCES.txt +0 -264
  279. {pycharter-0.0.20 → pycharter-0.0.23}/LICENSE +0 -0
  280. {pycharter-0.0.20 → pycharter-0.0.23}/api/__init__.py +0 -0
  281. {pycharter-0.0.20 → pycharter-0.0.23}/api/dependencies/store.py +0 -0
  282. {pycharter-0.0.20 → pycharter-0.0.23}/api/models/__init__.py +0 -0
  283. {pycharter-0.0.20 → pycharter-0.0.23}/api/models/metadata_entities.py +0 -0
  284. {pycharter-0.0.20 → pycharter-0.0.23}/api/models/quality.py +0 -0
  285. {pycharter-0.0.20 → pycharter-0.0.23}/api/models/validation.py +0 -0
  286. {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/__init__.py +0 -0
  287. {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/__init__.py +0 -0
  288. {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/quality.py +0 -0
  289. {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/validation.py +0 -0
  290. {pycharter-0.0.20 → pycharter-0.0.23}/api/routes/v1/validation_jobs.py +0 -0
  291. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/cli.py +0 -0
  292. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/config.py +0 -0
  293. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/contract_builder/__init__.py +0 -0
  294. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/contract_builder/builder.py +0 -0
  295. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/contract_parser/__init__.py +0 -0
  296. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/contract_parser/parser.py +0 -0
  297. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/data/__init__.py +0 -0
  298. {pycharter-0.0.20/pycharter/data/templates → pycharter-0.0.23/pycharter/data/templates/contract}/template_coercion_rules.yaml +0 -0
  299. {pycharter-0.0.20/pycharter/data/templates → pycharter-0.0.23/pycharter/data/templates/contract}/template_contract.yaml +0 -0
  300. {pycharter-0.0.20/pycharter/data/templates → pycharter-0.0.23/pycharter/data/templates/contract}/template_metadata.yaml +0 -0
  301. {pycharter-0.0.20/pycharter/data/templates → pycharter-0.0.23/pycharter/data/templates/contract}/template_schema.yaml +0 -0
  302. {pycharter-0.0.20/pycharter/data/templates → pycharter-0.0.23/pycharter/data/templates/contract}/template_validation_rules.yaml +0 -0
  303. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/__init__.py +0 -0
  304. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/cli.py +0 -0
  305. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/README +0 -0
  306. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/env.py +0 -0
  307. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/script.py.mako +0 -0
  308. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20250115120000_add_tier2_tier3_entities.py +0 -0
  309. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20251209163657_799b73fe9f6c_initial_schema.py +0 -0
  310. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20251209164144_ae0efda02aa1_initial_schema.py +0 -0
  311. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20251217160146_f9995dc0f4b3_add_quality_tables.py +0 -0
  312. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20251217164915_8b08d78068e3_add_data_version_tracking.py +0 -0
  313. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20260110083000_a1b2c3d4e5f6_add_dead_letter_queue_table.py +0 -0
  314. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20260120000000_add_name_title_validation_constraints.py +0 -0
  315. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20260121000000_remove_artifact_versions_from_data_contracts.py +0 -0
  316. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/20260122000000_change_artifact_unique_constraints_to_title_version.py +0 -0
  317. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/migrations/versions/__init__.py +0 -0
  318. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/__init__.py +0 -0
  319. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/api_endpoint.py +0 -0
  320. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/coercion_rule.py +0 -0
  321. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/compliance_framework.py +0 -0
  322. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/data_contract.py +0 -0
  323. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/data_dependency.py +0 -0
  324. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/data_feed.py +0 -0
  325. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/dlq.py +0 -0
  326. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/domain.py +0 -0
  327. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/environment.py +0 -0
  328. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/metadata_record.py +0 -0
  329. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/owner.py +0 -0
  330. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/quality_metric.py +0 -0
  331. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/quality_violation.py +0 -0
  332. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/schema.py +0 -0
  333. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/storage_location.py +0 -0
  334. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/system.py +0 -0
  335. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/tag.py +0 -0
  336. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/models/validation_rule.py +0 -0
  337. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/schemas/.ipynb_checkpoints/data_contract-checkpoint.py +0 -0
  338. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/schemas/__init__.py +0 -0
  339. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/db/schemas/data_contract.py +0 -0
  340. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/__init__.py +0 -0
  341. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/checkpoint.py +0 -0
  342. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/config_generator.py +0 -0
  343. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/database.py +0 -0
  344. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/dlq.py +0 -0
  345. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/factory.py +0 -0
  346. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/etl_generator/progress.py +0 -0
  347. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/integrations/__init__.py +0 -0
  348. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/integrations/kafka.py +0 -0
  349. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/integrations/streaming.py +0 -0
  350. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/json_schema_converter/__init__.py +0 -0
  351. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/json_schema_converter/converter.py +0 -0
  352. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/json_schema_converter/reverse_converter.py +0 -0
  353. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/metadata_store/__init__.py +0 -0
  354. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/metadata_store/client.py +0 -0
  355. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/metadata_store/in_memory.py +0 -0
  356. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/metadata_store/mongodb.py +0 -0
  357. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/metadata_store/redis.py +0 -0
  358. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/py.typed +0 -0
  359. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/pydantic_generator/__init__.py +0 -0
  360. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/pydantic_generator/converter.py +0 -0
  361. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/pydantic_generator/generator.py +0 -0
  362. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/quality/__init__.py +0 -0
  363. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/quality/check.py +0 -0
  364. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/quality/cli.py +0 -0
  365. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/quality/metrics.py +0 -0
  366. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/quality/models.py +0 -0
  367. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/quality/profiling.py +0 -0
  368. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/quality/violations.py +0 -0
  369. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/runtime_validator/__init__.py +0 -0
  370. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/runtime_validator/decorators.py +0 -0
  371. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/runtime_validator/utils.py +0 -0
  372. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/runtime_validator/validator.py +0 -0
  373. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/runtime_validator/validator_core.py +0 -0
  374. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/runtime_validator/wrappers.py +0 -0
  375. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/__init__.py +0 -0
  376. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/coercions/__init__.py +0 -0
  377. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/coercions/builtin.py +0 -0
  378. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/json_schema_support.py +0 -0
  379. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/json_schema_validator.py +0 -0
  380. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/name_validator.py +0 -0
  381. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/schema_parser.py +0 -0
  382. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/schema_resolver.py +0 -0
  383. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/validations/__init__.py +0 -0
  384. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/shared/validations/builtin.py +0 -0
  385. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/utils/__init__.py +0 -0
  386. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/utils/value_injector.py +0 -0
  387. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter/utils/version.py +0 -0
  388. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter.egg-info/dependency_links.txt +0 -0
  389. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter.egg-info/entry_points.txt +0 -0
  390. {pycharter-0.0.20 → pycharter-0.0.23}/pycharter.egg-info/top_level.txt +0 -0
  391. {pycharter-0.0.20 → pycharter-0.0.23}/setup.cfg +0 -0
  392. {pycharter-0.0.20 → pycharter-0.0.23}/setup.py +0 -0
  393. {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_contract_builder.py +0 -0
  394. {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_contract_parser.py +0 -0
  395. {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_integration.py +0 -0
  396. {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_json_schema_compliance.py +0 -0
  397. {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_json_schema_converter.py +0 -0
  398. {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_metadata_stores.py +0 -0
  399. {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_pydantic_generator.py +0 -0
  400. {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_refs_and_definitions.py +0 -0
  401. {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_runtime_validator.py +0 -0
  402. {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_schema_parser.py +0 -0
  403. {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_value_injector.py +0 -0
  404. {pycharter-0.0.20 → pycharter-0.0.23}/tests/test_x_validators.py +0 -0
  405. {pycharter-0.0.20 → pycharter-0.0.23}/ui/__init__.py +0 -0
  406. {pycharter-0.0.20 → pycharter-0.0.23}/ui/build.py +0 -0
  407. {pycharter-0.0.20 → pycharter-0.0.23}/ui/dev.py +0 -0
  408. {pycharter-0.0.20 → pycharter-0.0.23}/ui/server.py +0 -0
  409. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/.gitkeep +0 -0
  410. {pycharter-0.0.20/ui/static/_next/static/tNTkVW6puVXC4bAm4WrHl → pycharter-0.0.23/ui/static/_next/static/2gKjNv6YvE6BcIdFthBLs}/_buildManifest.js +0 -0
  411. {pycharter-0.0.20/ui/static/_next/static/tNTkVW6puVXC4bAm4WrHl → pycharter-0.0.23/ui/static/_next/static/2gKjNv6YvE6BcIdFthBLs}/_ssgManifest.js +0 -0
  412. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/222442f6da32302a.js +0 -0
  413. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/247eb132b7f7b574.js +0 -0
  414. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/297d55555b71baba.js +0 -0
  415. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/2ab439ce003cd691.js +0 -0
  416. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/414e77373f8ff61c.js +0 -0
  417. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/49ca65abd26ae49e.js +0 -0
  418. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/652ad0aa26265c47.js +0 -0
  419. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/9667e7a3d359eb39.js +0 -0
  420. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/9c23f44fff36548a.js +0 -0
  421. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/a6dad97d9634a72d.js +0 -0
  422. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/b32a0963684b9933.js +0 -0
  423. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/c69f6cba366bd988.js +0 -0
  424. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/db913959c675cea6.js +0 -0
  425. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/f061a4be97bfc3b3.js +0 -0
  426. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/f2e7afeab1178138.js +0 -0
  427. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/ff1a16fafef87110.js +0 -0
  428. {pycharter-0.0.20 → pycharter-0.0.23}/ui/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +0 -0
  429. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static}/static/_next/static/chunks/5e04d10c4a7b58a3.js +0 -0
  430. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static}/static/_next/static/chunks/75d88a058d8ffaa6.js +0 -0
  431. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static}/static/_next/static/chunks/8c89634cf6bad76f.js +0 -0
  432. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/404/index.html +0 -0
  433. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/404.html +0 -0
  434. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/__next.__PAGE__.txt +0 -0
  435. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/__next._full.txt +0 -0
  436. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/__next._head.txt +0 -0
  437. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/__next._index.txt +0 -0
  438. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/__next._tree.txt +0 -0
  439. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_next/static/chunks/4e310fe5005770a3.css +0 -0
  440. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_next/static/chunks/5fc14c00a2779dc5.js +0 -0
  441. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_next/static/chunks/b584574fdc8ab13e.js +0 -0
  442. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_next/static/chunks/d5989c94d3614b3a.js +0 -0
  443. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/__next._full.txt +0 -0
  444. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/__next._head.txt +0 -0
  445. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/__next._index.txt +0 -0
  446. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/__next._not-found.__PAGE__.txt +0 -0
  447. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/__next._not-found.txt +0 -0
  448. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/__next._tree.txt +0 -0
  449. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/index.html +0 -0
  450. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/_not-found/index.txt +0 -0
  451. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/__next._full.txt +0 -0
  452. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/__next._head.txt +0 -0
  453. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/__next._index.txt +0 -0
  454. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/__next._tree.txt +0 -0
  455. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/__next.contracts.__PAGE__.txt +0 -0
  456. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/__next.contracts.txt +0 -0
  457. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/index.html +0 -0
  458. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/contracts/index.txt +0 -0
  459. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/__next._full.txt +0 -0
  460. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/__next._head.txt +0 -0
  461. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/__next._index.txt +0 -0
  462. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/__next._tree.txt +0 -0
  463. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/__next.documentation.__PAGE__.txt +0 -0
  464. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/__next.documentation.txt +0 -0
  465. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/index.html +0 -0
  466. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/documentation/index.txt +0 -0
  467. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/index.html +0 -0
  468. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/index.txt +0 -0
  469. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/__next._full.txt +0 -0
  470. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/__next._head.txt +0 -0
  471. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/__next._index.txt +0 -0
  472. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/__next._tree.txt +0 -0
  473. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/__next.metadata.__PAGE__.txt +0 -0
  474. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/__next.metadata.txt +0 -0
  475. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/index.html +0 -0
  476. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/metadata/index.txt +0 -0
  477. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/__next._full.txt +0 -0
  478. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/__next._head.txt +0 -0
  479. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/__next._index.txt +0 -0
  480. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/__next._tree.txt +0 -0
  481. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/__next.quality.__PAGE__.txt +0 -0
  482. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/__next.quality.txt +0 -0
  483. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/index.html +0 -0
  484. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/quality/index.txt +0 -0
  485. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/__next._full.txt +0 -0
  486. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/__next._head.txt +0 -0
  487. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/__next._index.txt +0 -0
  488. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/__next._tree.txt +0 -0
  489. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/__next.rules.__PAGE__.txt +0 -0
  490. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/__next.rules.txt +0 -0
  491. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/index.html +0 -0
  492. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/rules/index.txt +0 -0
  493. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/__next._full.txt +0 -0
  494. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/__next._head.txt +0 -0
  495. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/__next._index.txt +0 -0
  496. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/__next._tree.txt +0 -0
  497. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/__next.schemas.__PAGE__.txt +0 -0
  498. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/__next.schemas.txt +0 -0
  499. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/index.html +0 -0
  500. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/schemas/index.txt +0 -0
  501. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/__next._full.txt +0 -0
  502. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/__next._head.txt +0 -0
  503. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/__next._index.txt +0 -0
  504. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/__next._tree.txt +0 -0
  505. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/__next.settings.__PAGE__.txt +0 -0
  506. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/__next.settings.txt +0 -0
  507. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/index.html +0 -0
  508. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/settings/index.txt +0 -0
  509. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/__next._full.txt +0 -0
  510. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/__next._head.txt +0 -0
  511. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/__next._index.txt +0 -0
  512. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/__next._tree.txt +0 -0
  513. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/__next.validation.__PAGE__.txt +0 -0
  514. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/__next.validation.txt +0 -0
  515. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/index.html +0 -0
  516. {pycharter-0.0.20/ui → pycharter-0.0.23/ui/static/static}/static/validation/index.txt +0 -0
  517. {pycharter-0.0.20 → pycharter-0.0.23}/worker/__init__.py +0 -0
  518. {pycharter-0.0.20 → pycharter-0.0.23}/worker/cli.py +0 -0
  519. {pycharter-0.0.20 → pycharter-0.0.23}/worker/models.py +0 -0
  520. {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.20
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
- # 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
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 PostgresMetadataStore, parse_contract_file
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 PostgreSQL metadata store (or MongoDBMetadataStore, RedisMetadataStore, etc.)
306
- store = PostgresMetadataStore(connection_string="postgresql://user:pass@localhost:5432/pycharter")
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
- **Two Validation Modes**:
529
+ **Example - Validator Class (Recommended)**:
530
+ ```python
531
+ from pycharter import Validator, SQLiteMetadataStore
426
532
 
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()`
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. **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()`
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
- **Example - Database-Backed**:
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, InMemoryMetadataStore
553
+ from pycharter import validate_with_store, validate_with_contract, SQLiteMetadataStore
438
554
 
439
- # Store and validate with database
440
- store = InMemoryMetadataStore()
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
- if result.is_valid:
447
- print(f"Valid user: {result.data.name}")
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 - Contract-Based (No Database)**:
564
+ **Example - Low-Level (When You Have a Model)**:
451
565
  ```python
452
- from pycharter import validate_with_contract, get_model_from_contract, validate
566
+ from pycharter import from_dict, validate, validate_batch
453
567
 
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
- )
568
+ # Generate model
569
+ UserModel = from_dict(schema, "User")
459
570
 
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)
571
+ # Validate single record
572
+ result = validate(UserModel, {"name": "Alice", "age": 30})
464
573
 
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)
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
- PostgresMetadataStore,
645
+ SQLiteMetadataStore,
537
646
  from_dict,
538
- validate,
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 = PostgresMetadataStore(connection_string="postgresql://user:pass@localhost:5432/pycharter")
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(UserModel, raw_data)
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
- Charter supports **coercion** (pre-validation transformation) and **validation** (post-validation checks):
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
- ### Main Functions
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 file
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
- - **`schema_to_model(schema: dict, model_name: str = "DynamicModel")`** - Low-level model generator
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
- # Clean previous builds
985
- make clean
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
- # Build package
988
- make build
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
- # Test on TestPyPI
991
- make publish-test
1212
+ The workflow automatically:
1213
+ - ✅ Builds UI
1214
+ - ✅ Builds Python package
1215
+ - ✅ Publishes to PyPI (using Trusted Publishing)
992
1216
 
993
- # Publish to PyPI
994
- make publish
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: