pycharter 0.0.24__py3-none-any.whl → 0.0.26__py3-none-any.whl

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 (567) hide show
  1. pycharter/__init__.py +6 -0
  2. pycharter/api/README.md +340 -0
  3. {api → pycharter/api}/__init__.py +1 -1
  4. {api → pycharter/api}/dependencies/__init__.py +2 -2
  5. pycharter/api/dependencies/auth.py +158 -0
  6. {api → pycharter/api}/main.py +32 -4
  7. {api → pycharter/api}/models/__init__.py +4 -4
  8. pycharter/api/models/etl.py +66 -0
  9. {api → pycharter/api}/routes/v1/__init__.py +5 -1
  10. pycharter/api/routes/v1/auth.py +97 -0
  11. {api → pycharter/api}/routes/v1/contracts.py +14 -12
  12. {api → pycharter/api}/routes/v1/docs.py +2 -2
  13. pycharter/api/routes/v1/etl.py +131 -0
  14. {api → pycharter/api}/routes/v1/evolution.py +2 -2
  15. {api → pycharter/api}/routes/v1/metadata.py +5 -5
  16. {api → pycharter/api}/routes/v1/quality.py +3 -3
  17. {api → pycharter/api}/routes/v1/schemas.py +1 -1
  18. {api → pycharter/api}/routes/v1/settings.py +1 -1
  19. {api → pycharter/api}/routes/v1/tracking.py +1 -1
  20. {api → pycharter/api}/routes/v1/validation.py +2 -2
  21. {api → pycharter/api}/routes/v1/validation_jobs.py +3 -3
  22. pycharter/cli.py +9 -11
  23. pycharter/config.py +69 -0
  24. pycharter/contract_builder/builder.py +32 -37
  25. pycharter/data/seed/compliance_frameworks.yaml +22 -0
  26. pycharter/data/seed/contracts.yaml +130 -0
  27. pycharter/data/seed/data_feeds.yaml +22 -0
  28. pycharter/data/seed/domains.yaml +13 -0
  29. pycharter/data/seed/environments.yaml +19 -0
  30. pycharter/data/seed/owners.yaml +21 -0
  31. pycharter/data/seed/systems.yaml +13 -0
  32. pycharter/data/seed/tags.yaml +25 -0
  33. pycharter/data/templates/contract/README.md +161 -0
  34. pycharter/data/templates/contract/template_contract.yaml +37 -0
  35. pycharter/data/templates/etl/README.md +1 -1
  36. pycharter/data/templates/etl/extract_with_validation.yaml +86 -0
  37. pycharter/data/templates/etl/load_with_validation.yaml +111 -0
  38. pycharter/data/templates/etl/settings.yaml +55 -0
  39. pycharter/db/README.md +179 -0
  40. pycharter/db/cli.py +126 -4
  41. pycharter/db/migrations/versions/20260122000000_change_artifact_unique_constraints_to_title_version.py +2 -2
  42. pycharter/db/schemas/README.md +96 -0
  43. pycharter/etl_generator/ASYNC_AND_EXECUTION.md +91 -0
  44. pycharter/etl_generator/INTERFACES.md +142 -0
  45. pycharter/etl_generator/README.md +271 -0
  46. pycharter/etl_generator/TRANSFORMATION_GUIDE.md +452 -0
  47. pycharter/etl_generator/__init__.py +47 -11
  48. pycharter/etl_generator/config_models.py +673 -0
  49. pycharter/etl_generator/config_validator.py +133 -157
  50. pycharter/etl_generator/context.py +3 -0
  51. pycharter/etl_generator/database.py +5 -1
  52. pycharter/etl_generator/extractors/__init__.py +4 -2
  53. pycharter/etl_generator/extractors/cloud_storage.py +9 -9
  54. pycharter/etl_generator/extractors/database.py +2 -2
  55. pycharter/etl_generator/extractors/factory.py +15 -33
  56. pycharter/etl_generator/extractors/file.py +2 -2
  57. pycharter/etl_generator/extractors/http.py +2 -2
  58. pycharter/etl_generator/extractors/mongodb.py +393 -0
  59. pycharter/etl_generator/extractors/streaming.py +2 -2
  60. pycharter/etl_generator/loaders/__init__.py +15 -9
  61. pycharter/etl_generator/loaders/{cloud_storage_loader.py → cloud_storage.py} +95 -2
  62. pycharter/etl_generator/loaders/factory.py +16 -29
  63. pycharter/etl_generator/loaders/file.py +135 -1
  64. pycharter/etl_generator/loaders/mongodb.py +416 -0
  65. pycharter/etl_generator/pipeline.py +283 -164
  66. pycharter/etl_generator/result.py +16 -0
  67. pycharter/etl_generator/schemas/__init__.py +71 -42
  68. pycharter/etl_generator/transformers/config.py +3 -2
  69. pycharter/etl_generator/transformers/simple_operations.py +57 -4
  70. pycharter/etl_generator/validation.py +551 -0
  71. pycharter/metadata_store/README.md +229 -0
  72. pycharter/quality/README.md +235 -0
  73. pycharter/runtime_validator/__init__.py +7 -0
  74. pycharter/runtime_validator/utils.py +33 -0
  75. pycharter/runtime_validator/validator.py +13 -10
  76. pycharter/ui/.eslintrc.json +4 -0
  77. pycharter/ui/README.md +186 -0
  78. {ui → pycharter/ui}/__init__.py +3 -3
  79. pycharter/ui/components.json +17 -0
  80. pycharter/ui/package-lock.json +6617 -0
  81. pycharter/ui/package.json +37 -0
  82. {ui → pycharter/ui}/server.py +7 -8
  83. pycharter/ui/static/404/index.html +1 -0
  84. pycharter/ui/static/404.html +1 -0
  85. pycharter/ui/static/__next.__PAGE__.txt +10 -0
  86. pycharter/ui/static/__next._full.txt +30 -0
  87. pycharter/ui/static/__next._head.txt +7 -0
  88. pycharter/ui/static/__next._index.txt +9 -0
  89. pycharter/ui/static/__next._tree.txt +2 -0
  90. pycharter/ui/static/_next/static/YCnlK66gA7FV5vvcixspB/_clientMiddlewareManifest.json +1 -0
  91. pycharter/ui/static/_next/static/chunks/0fc1f70b787b8845.js +1 -0
  92. pycharter/ui/static/_next/static/chunks/17bb8075d7b75663.css +1 -0
  93. pycharter/ui/static/_next/static/chunks/381932864dcbfdb8.js +1 -0
  94. pycharter/ui/static/_next/static/chunks/4c951b8e4507e2b3.js +1 -0
  95. pycharter/ui/static/_next/static/chunks/68b87a6f65abd3ed.js +1 -0
  96. pycharter/ui/static/_next/static/chunks/78572617b8fae189.js +1 -0
  97. pycharter/ui/static/_next/static/chunks/8b7be2803e3fe184.js +1 -0
  98. pycharter/ui/static/_next/static/chunks/a8e529fd1e67f121.js +1 -0
  99. pycharter/ui/static/_next/static/chunks/c35d998f80be3ff5.js +1 -0
  100. pycharter/ui/static/_next/static/chunks/e453aa5d01c32c17.js +1 -0
  101. pycharter/ui/static/_next/static/chunks/f2d240eb057f898a.js +970 -0
  102. pycharter/ui/static/_next/static/chunks/f7722448f6040846.js +1 -0
  103. pycharter/ui/static/_not-found/__next._full.txt +17 -0
  104. pycharter/ui/static/_not-found/__next._head.txt +7 -0
  105. pycharter/ui/static/_not-found/__next._index.txt +9 -0
  106. pycharter/ui/static/_not-found/__next._not-found.__PAGE__.txt +5 -0
  107. pycharter/ui/static/_not-found/__next._not-found.txt +4 -0
  108. pycharter/ui/static/_not-found/__next._tree.txt +2 -0
  109. pycharter/ui/static/_not-found/index.html +1 -0
  110. pycharter/ui/static/_not-found/index.txt +17 -0
  111. pycharter/ui/static/contracts/__next._full.txt +21 -0
  112. pycharter/ui/static/contracts/__next._head.txt +7 -0
  113. pycharter/ui/static/contracts/__next._index.txt +9 -0
  114. pycharter/ui/static/contracts/__next._tree.txt +2 -0
  115. pycharter/ui/static/contracts/__next.contracts.__PAGE__.txt +9 -0
  116. pycharter/ui/static/contracts/__next.contracts.txt +4 -0
  117. pycharter/ui/static/contracts/index.html +1 -0
  118. pycharter/ui/static/contracts/index.txt +21 -0
  119. pycharter/ui/static/documentation/__next._full.txt +21 -0
  120. pycharter/ui/static/documentation/__next._head.txt +7 -0
  121. pycharter/ui/static/documentation/__next._index.txt +9 -0
  122. pycharter/ui/static/documentation/__next._tree.txt +2 -0
  123. pycharter/ui/static/documentation/__next.documentation.__PAGE__.txt +9 -0
  124. pycharter/ui/static/documentation/__next.documentation.txt +4 -0
  125. pycharter/ui/static/documentation/index.html +93 -0
  126. pycharter/ui/static/documentation/index.txt +21 -0
  127. pycharter/ui/static/etl/__next._full.txt +21 -0
  128. pycharter/ui/static/etl/__next._head.txt +7 -0
  129. pycharter/ui/static/etl/__next._index.txt +9 -0
  130. pycharter/ui/static/etl/__next._tree.txt +2 -0
  131. pycharter/ui/static/etl/__next.etl.__PAGE__.txt +9 -0
  132. pycharter/ui/static/etl/__next.etl.txt +4 -0
  133. pycharter/ui/static/etl/index.html +2 -0
  134. pycharter/ui/static/etl/index.txt +21 -0
  135. pycharter/ui/static/index.html +1 -0
  136. pycharter/ui/static/index.txt +30 -0
  137. pycharter/ui/static/metadata/__next._full.txt +21 -0
  138. pycharter/ui/static/metadata/__next._head.txt +7 -0
  139. pycharter/ui/static/metadata/__next._index.txt +9 -0
  140. pycharter/ui/static/metadata/__next._tree.txt +2 -0
  141. pycharter/ui/static/metadata/__next.metadata.__PAGE__.txt +9 -0
  142. pycharter/ui/static/metadata/__next.metadata.txt +4 -0
  143. pycharter/ui/static/metadata/index.html +1 -0
  144. pycharter/ui/static/metadata/index.txt +21 -0
  145. pycharter/ui/static/quality/__next._full.txt +21 -0
  146. pycharter/ui/static/quality/__next._head.txt +7 -0
  147. pycharter/ui/static/quality/__next._index.txt +9 -0
  148. pycharter/ui/static/quality/__next._tree.txt +2 -0
  149. pycharter/ui/static/quality/__next.quality.__PAGE__.txt +9 -0
  150. pycharter/ui/static/quality/__next.quality.txt +4 -0
  151. pycharter/ui/static/quality/index.html +2 -0
  152. pycharter/ui/static/quality/index.txt +21 -0
  153. pycharter/ui/static/rules/__next._full.txt +21 -0
  154. pycharter/ui/static/rules/__next._head.txt +7 -0
  155. pycharter/ui/static/rules/__next._index.txt +9 -0
  156. pycharter/ui/static/rules/__next._tree.txt +2 -0
  157. pycharter/ui/static/rules/__next.rules.__PAGE__.txt +9 -0
  158. pycharter/ui/static/rules/__next.rules.txt +4 -0
  159. pycharter/ui/static/rules/index.html +1 -0
  160. pycharter/ui/static/rules/index.txt +21 -0
  161. pycharter/ui/static/schemas/__next._full.txt +21 -0
  162. pycharter/ui/static/schemas/__next._head.txt +7 -0
  163. pycharter/ui/static/schemas/__next._index.txt +9 -0
  164. pycharter/ui/static/schemas/__next._tree.txt +2 -0
  165. pycharter/ui/static/schemas/__next.schemas.__PAGE__.txt +9 -0
  166. pycharter/ui/static/schemas/__next.schemas.txt +4 -0
  167. pycharter/ui/static/schemas/index.html +1 -0
  168. pycharter/ui/static/schemas/index.txt +21 -0
  169. pycharter/ui/static/settings/__next._full.txt +21 -0
  170. pycharter/ui/static/settings/__next._head.txt +7 -0
  171. pycharter/ui/static/settings/__next._index.txt +9 -0
  172. pycharter/ui/static/settings/__next._tree.txt +2 -0
  173. pycharter/ui/static/settings/__next.settings.__PAGE__.txt +9 -0
  174. pycharter/ui/static/settings/__next.settings.txt +4 -0
  175. pycharter/ui/static/settings/index.html +1 -0
  176. pycharter/ui/static/settings/index.txt +21 -0
  177. pycharter/ui/static/static/_next/static/2gKjNv6YvE6BcIdFthBLs/_clientMiddlewareManifest.json +1 -0
  178. pycharter/ui/static/static/static/_next/static/0rYA78L88aUyD2Uh38hhX/_clientMiddlewareManifest.json +1 -0
  179. pycharter/ui/static/static/static/_next/static/chunks/f7d1a90dd75d2572.js +1 -0
  180. pycharter/ui/static/static/static/static/.gitkeep +0 -0
  181. pycharter/ui/static/static/static/static/_next/static/chunks/222442f6da32302a.js +1 -0
  182. pycharter/ui/static/static/static/static/_next/static/chunks/247eb132b7f7b574.js +1 -0
  183. pycharter/ui/static/static/static/static/_next/static/chunks/297d55555b71baba.js +1 -0
  184. pycharter/ui/static/static/static/static/_next/static/chunks/414e77373f8ff61c.js +1 -0
  185. pycharter/ui/static/static/static/static/_next/static/chunks/652ad0aa26265c47.js +2 -0
  186. pycharter/ui/static/static/static/static/_next/static/chunks/9c23f44fff36548a.js +1 -0
  187. pycharter/ui/static/static/static/static/_next/static/chunks/a6dad97d9634a72d.js +1 -0
  188. pycharter/ui/static/static/static/static/_next/static/chunks/b32a0963684b9933.js +4 -0
  189. pycharter/ui/static/static/static/static/_next/static/chunks/db913959c675cea6.js +1 -0
  190. pycharter/ui/static/static/static/static/_next/static/chunks/f2e7afeab1178138.js +1 -0
  191. pycharter/ui/static/static/static/static/_next/static/chunks/ff1a16fafef87110.js +1 -0
  192. pycharter/ui/static/static/static/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +3 -0
  193. pycharter/ui/static/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_buildManifest.js +11 -0
  194. pycharter/ui/static/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_clientMiddlewareManifest.json +1 -0
  195. pycharter/ui/static/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_ssgManifest.js +1 -0
  196. pycharter/ui/static/validation/__next._full.txt +21 -0
  197. pycharter/ui/static/validation/__next._head.txt +7 -0
  198. pycharter/ui/static/validation/__next._index.txt +9 -0
  199. pycharter/ui/static/validation/__next._tree.txt +2 -0
  200. pycharter/ui/static/validation/__next.validation.__PAGE__.txt +9 -0
  201. pycharter/ui/static/validation/__next.validation.txt +4 -0
  202. pycharter/ui/static/validation/index.html +1 -0
  203. pycharter/ui/static/validation/index.txt +21 -0
  204. pycharter/ui/tsconfig.json +42 -0
  205. pycharter/worker/README.md +187 -0
  206. pycharter/worker/backends/__init__.py +8 -0
  207. pycharter/worker/backends/base.py +46 -0
  208. pycharter/worker/backends/spark.py +233 -0
  209. {worker → pycharter/worker}/cli.py +1 -1
  210. {worker → pycharter/worker}/processor.py +2 -2
  211. pycharter/worker/queue/__init__.py +8 -0
  212. pycharter/worker/queue/redis_queue.py +147 -0
  213. {pycharter-0.0.24.dist-info → pycharter-0.0.26.dist-info}/METADATA +57 -26
  214. pycharter-0.0.26.dist-info/RECORD +702 -0
  215. pycharter-0.0.26.dist-info/top_level.txt +1 -0
  216. pycharter/etl_generator/config_loader.py +0 -394
  217. pycharter/etl_generator/loaders/cloud.py +0 -87
  218. pycharter/etl_generator/loaders/file_loader.py +0 -130
  219. pycharter-0.0.24.dist-info/RECORD +0 -543
  220. pycharter-0.0.24.dist-info/top_level.txt +0 -4
  221. {api → pycharter/api}/dependencies/database.py +0 -0
  222. {api → pycharter/api}/dependencies/store.py +0 -0
  223. {api → pycharter/api}/models/contracts.py +0 -0
  224. {api → pycharter/api}/models/docs.py +0 -0
  225. {api → pycharter/api}/models/evolution.py +0 -0
  226. {api → pycharter/api}/models/metadata.py +0 -0
  227. {api → pycharter/api}/models/metadata_entities.py +0 -0
  228. {api → pycharter/api}/models/quality.py +0 -0
  229. {api → pycharter/api}/models/schemas.py +0 -0
  230. {api → pycharter/api}/models/tracking.py +0 -0
  231. {api → pycharter/api}/models/validation.py +0 -0
  232. {api → pycharter/api}/routes/__init__.py +0 -0
  233. {api → pycharter/api}/routes/v1/templates.py +0 -0
  234. {api → pycharter/api}/utils.py +0 -0
  235. {ui → pycharter/ui}/build.py +0 -0
  236. {ui → pycharter/ui}/dev.py +0 -0
  237. {ui → pycharter/ui}/static/.gitkeep +0 -0
  238. {ui/static/_next/static/2gKjNv6YvE6BcIdFthBLs → pycharter/ui/static/_next/static/YCnlK66gA7FV5vvcixspB}/_buildManifest.js +0 -0
  239. {ui/static/_next/static/2gKjNv6YvE6BcIdFthBLs → pycharter/ui/static/_next/static/YCnlK66gA7FV5vvcixspB}/_ssgManifest.js +0 -0
  240. {ui → pycharter/ui}/static/_next/static/chunks/222442f6da32302a.js +0 -0
  241. {ui → pycharter/ui}/static/_next/static/chunks/247eb132b7f7b574.js +0 -0
  242. {ui → pycharter/ui}/static/_next/static/chunks/297d55555b71baba.js +0 -0
  243. {ui → pycharter/ui}/static/_next/static/chunks/414e77373f8ff61c.js +0 -0
  244. {ui → pycharter/ui}/static/_next/static/chunks/652ad0aa26265c47.js +0 -0
  245. {ui → pycharter/ui}/static/_next/static/chunks/9c23f44fff36548a.js +0 -0
  246. {ui → pycharter/ui}/static/_next/static/chunks/a6dad97d9634a72d.js +0 -0
  247. {ui → pycharter/ui}/static/_next/static/chunks/b32a0963684b9933.js +0 -0
  248. {ui → pycharter/ui}/static/_next/static/chunks/db913959c675cea6.js +0 -0
  249. {ui → pycharter/ui}/static/_next/static/chunks/f2e7afeab1178138.js +0 -0
  250. {ui → pycharter/ui}/static/_next/static/chunks/f7d1a90dd75d2572.js +0 -0
  251. {ui → pycharter/ui}/static/_next/static/chunks/ff1a16fafef87110.js +0 -0
  252. {ui → pycharter/ui}/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +0 -0
  253. {ui → pycharter/ui}/static/static/.gitkeep +0 -0
  254. {ui → pycharter/ui/static}/static/404/index.html +0 -0
  255. {ui → pycharter/ui/static}/static/404.html +0 -0
  256. {ui → pycharter/ui/static}/static/__next.__PAGE__.txt +0 -0
  257. {ui → pycharter/ui/static}/static/__next._full.txt +0 -0
  258. {ui → pycharter/ui/static}/static/__next._head.txt +0 -0
  259. {ui → pycharter/ui/static}/static/__next._index.txt +0 -0
  260. {ui → pycharter/ui/static}/static/__next._tree.txt +0 -0
  261. {ui/static/static/_next/static/0rYA78L88aUyD2Uh38hhX → pycharter/ui/static/static/_next/static/2gKjNv6YvE6BcIdFthBLs}/_buildManifest.js +0 -0
  262. {ui/static/static/_next/static/0rYA78L88aUyD2Uh38hhX → pycharter/ui/static/static/_next/static/2gKjNv6YvE6BcIdFthBLs}/_ssgManifest.js +0 -0
  263. {ui → pycharter/ui/static}/static/_next/static/chunks/13d4a0fbd74c1ee4.js +0 -0
  264. {ui → pycharter/ui}/static/static/_next/static/chunks/222442f6da32302a.js +0 -0
  265. {ui → pycharter/ui}/static/static/_next/static/chunks/247eb132b7f7b574.js +0 -0
  266. {ui → pycharter/ui/static}/static/_next/static/chunks/26dfc590f7714c03.js +0 -0
  267. {ui → pycharter/ui}/static/static/_next/static/chunks/297d55555b71baba.js +0 -0
  268. {ui → pycharter/ui/static}/static/_next/static/chunks/2ab439ce003cd691.js +0 -0
  269. {ui → pycharter/ui/static}/static/_next/static/chunks/2edb43b48432ac04.js +0 -0
  270. {ui → pycharter/ui/static}/static/_next/static/chunks/34d289e6db2ef551.js +0 -0
  271. {ui → pycharter/ui}/static/static/_next/static/chunks/414e77373f8ff61c.js +0 -0
  272. {ui → pycharter/ui/static}/static/_next/static/chunks/49ca65abd26ae49e.js +0 -0
  273. {ui → pycharter/ui}/static/static/_next/static/chunks/652ad0aa26265c47.js +0 -0
  274. {ui → pycharter/ui/static}/static/_next/static/chunks/9667e7a3d359eb39.js +0 -0
  275. {ui → pycharter/ui/static}/static/_next/static/chunks/99508d9d5869cc27.js +0 -0
  276. {ui → pycharter/ui}/static/static/_next/static/chunks/9c23f44fff36548a.js +0 -0
  277. {ui → pycharter/ui}/static/static/_next/static/chunks/a6dad97d9634a72d.js +0 -0
  278. {ui → pycharter/ui/static}/static/_next/static/chunks/b313c35a6ba76574.js +0 -0
  279. {ui → pycharter/ui}/static/static/_next/static/chunks/b32a0963684b9933.js +0 -0
  280. {ui → pycharter/ui/static}/static/_next/static/chunks/c69f6cba366bd988.js +0 -0
  281. {ui → pycharter/ui/static}/static/_next/static/chunks/d2363397e1b2bcab.css +0 -0
  282. {ui → pycharter/ui}/static/static/_next/static/chunks/db913959c675cea6.js +0 -0
  283. {ui → pycharter/ui/static}/static/_next/static/chunks/f061a4be97bfc3b3.js +0 -0
  284. {ui → pycharter/ui}/static/static/_next/static/chunks/f2e7afeab1178138.js +0 -0
  285. {ui → pycharter/ui}/static/static/_next/static/chunks/f7d1a90dd75d2572.js +0 -0
  286. {ui → pycharter/ui}/static/static/_next/static/chunks/ff1a16fafef87110.js +0 -0
  287. {ui → pycharter/ui}/static/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +0 -0
  288. {ui → pycharter/ui/static}/static/_not-found/__next._full.txt +0 -0
  289. {ui → pycharter/ui/static}/static/_not-found/__next._head.txt +0 -0
  290. {ui → pycharter/ui/static}/static/_not-found/__next._index.txt +0 -0
  291. {ui → pycharter/ui/static}/static/_not-found/__next._not-found.__PAGE__.txt +0 -0
  292. {ui → pycharter/ui/static}/static/_not-found/__next._not-found.txt +0 -0
  293. {ui → pycharter/ui/static}/static/_not-found/__next._tree.txt +0 -0
  294. {ui → pycharter/ui/static}/static/_not-found/index.html +0 -0
  295. {ui → pycharter/ui/static}/static/_not-found/index.txt +0 -0
  296. {ui → pycharter/ui/static}/static/contracts/__next._full.txt +0 -0
  297. {ui → pycharter/ui/static}/static/contracts/__next._head.txt +0 -0
  298. {ui → pycharter/ui/static}/static/contracts/__next._index.txt +0 -0
  299. {ui → pycharter/ui/static}/static/contracts/__next._tree.txt +0 -0
  300. {ui → pycharter/ui/static}/static/contracts/__next.contracts.__PAGE__.txt +0 -0
  301. {ui → pycharter/ui/static}/static/contracts/__next.contracts.txt +0 -0
  302. {ui → pycharter/ui/static}/static/contracts/index.html +0 -0
  303. {ui → pycharter/ui/static}/static/contracts/index.txt +0 -0
  304. {ui → pycharter/ui/static}/static/documentation/__next._full.txt +0 -0
  305. {ui → pycharter/ui/static}/static/documentation/__next._head.txt +0 -0
  306. {ui → pycharter/ui/static}/static/documentation/__next._index.txt +0 -0
  307. {ui → pycharter/ui/static}/static/documentation/__next._tree.txt +0 -0
  308. {ui → pycharter/ui/static}/static/documentation/__next.documentation.__PAGE__.txt +0 -0
  309. {ui → pycharter/ui/static}/static/documentation/__next.documentation.txt +0 -0
  310. {ui → pycharter/ui/static}/static/documentation/index.html +0 -0
  311. {ui → pycharter/ui/static}/static/documentation/index.txt +0 -0
  312. {ui → pycharter/ui/static}/static/index.html +0 -0
  313. {ui → pycharter/ui/static}/static/index.txt +0 -0
  314. {ui → pycharter/ui/static}/static/metadata/__next._full.txt +0 -0
  315. {ui → pycharter/ui/static}/static/metadata/__next._head.txt +0 -0
  316. {ui → pycharter/ui/static}/static/metadata/__next._index.txt +0 -0
  317. {ui → pycharter/ui/static}/static/metadata/__next._tree.txt +0 -0
  318. {ui → pycharter/ui/static}/static/metadata/__next.metadata.__PAGE__.txt +0 -0
  319. {ui → pycharter/ui/static}/static/metadata/__next.metadata.txt +0 -0
  320. {ui → pycharter/ui/static}/static/metadata/index.html +0 -0
  321. {ui → pycharter/ui/static}/static/metadata/index.txt +0 -0
  322. {ui → pycharter/ui/static}/static/quality/__next._full.txt +0 -0
  323. {ui → pycharter/ui/static}/static/quality/__next._head.txt +0 -0
  324. {ui → pycharter/ui/static}/static/quality/__next._index.txt +0 -0
  325. {ui → pycharter/ui/static}/static/quality/__next._tree.txt +0 -0
  326. {ui → pycharter/ui/static}/static/quality/__next.quality.__PAGE__.txt +0 -0
  327. {ui → pycharter/ui/static}/static/quality/__next.quality.txt +0 -0
  328. {ui → pycharter/ui/static}/static/quality/index.html +0 -0
  329. {ui → pycharter/ui/static}/static/quality/index.txt +0 -0
  330. {ui → pycharter/ui/static}/static/rules/__next._full.txt +0 -0
  331. {ui → pycharter/ui/static}/static/rules/__next._head.txt +0 -0
  332. {ui → pycharter/ui/static}/static/rules/__next._index.txt +0 -0
  333. {ui → pycharter/ui/static}/static/rules/__next._tree.txt +0 -0
  334. {ui → pycharter/ui/static}/static/rules/__next.rules.__PAGE__.txt +0 -0
  335. {ui → pycharter/ui/static}/static/rules/__next.rules.txt +0 -0
  336. {ui → pycharter/ui/static}/static/rules/index.html +0 -0
  337. {ui → pycharter/ui/static}/static/rules/index.txt +0 -0
  338. {ui → pycharter/ui/static}/static/schemas/__next._full.txt +0 -0
  339. {ui → pycharter/ui/static}/static/schemas/__next._head.txt +0 -0
  340. {ui → pycharter/ui/static}/static/schemas/__next._index.txt +0 -0
  341. {ui → pycharter/ui/static}/static/schemas/__next._tree.txt +0 -0
  342. {ui → pycharter/ui/static}/static/schemas/__next.schemas.__PAGE__.txt +0 -0
  343. {ui → pycharter/ui/static}/static/schemas/__next.schemas.txt +0 -0
  344. {ui → pycharter/ui/static}/static/schemas/index.html +0 -0
  345. {ui → pycharter/ui/static}/static/schemas/index.txt +0 -0
  346. {ui → pycharter/ui/static}/static/settings/__next._full.txt +0 -0
  347. {ui → pycharter/ui/static}/static/settings/__next._head.txt +0 -0
  348. {ui → pycharter/ui/static}/static/settings/__next._index.txt +0 -0
  349. {ui → pycharter/ui/static}/static/settings/__next._tree.txt +0 -0
  350. {ui → pycharter/ui/static}/static/settings/__next.settings.__PAGE__.txt +0 -0
  351. {ui → pycharter/ui/static}/static/settings/__next.settings.txt +0 -0
  352. {ui → pycharter/ui/static}/static/settings/index.html +0 -0
  353. {ui → pycharter/ui/static}/static/settings/index.txt +0 -0
  354. {ui → pycharter/ui}/static/static/static/.gitkeep +0 -0
  355. {ui → pycharter/ui/static}/static/static/404/index.html +0 -0
  356. {ui → pycharter/ui/static}/static/static/404.html +0 -0
  357. {ui → pycharter/ui/static}/static/static/__next.__PAGE__.txt +0 -0
  358. {ui → pycharter/ui/static}/static/static/__next._full.txt +0 -0
  359. {ui → pycharter/ui/static}/static/static/__next._head.txt +0 -0
  360. {ui → pycharter/ui/static}/static/static/__next._index.txt +0 -0
  361. {ui → pycharter/ui/static}/static/static/__next._tree.txt +0 -0
  362. {ui/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl → pycharter/ui/static/static/static/_next/static/0rYA78L88aUyD2Uh38hhX}/_buildManifest.js +0 -0
  363. {ui/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl → pycharter/ui/static/static/static/_next/static/0rYA78L88aUyD2Uh38hhX}/_ssgManifest.js +0 -0
  364. {ui → pycharter/ui/static}/static/static/_next/static/chunks/13d4a0fbd74c1ee4.js +0 -0
  365. {ui → pycharter/ui}/static/static/static/_next/static/chunks/222442f6da32302a.js +0 -0
  366. {ui → pycharter/ui}/static/static/static/_next/static/chunks/247eb132b7f7b574.js +0 -0
  367. {ui → pycharter/ui}/static/static/static/_next/static/chunks/297d55555b71baba.js +0 -0
  368. {ui → pycharter/ui/static}/static/static/_next/static/chunks/2ab439ce003cd691.js +0 -0
  369. {ui → pycharter/ui/static}/static/static/_next/static/chunks/2edb43b48432ac04.js +0 -0
  370. {ui → pycharter/ui}/static/static/static/_next/static/chunks/414e77373f8ff61c.js +0 -0
  371. {ui → pycharter/ui/static}/static/static/_next/static/chunks/49ca65abd26ae49e.js +0 -0
  372. {ui → pycharter/ui/static}/static/static/_next/static/chunks/5e04d10c4a7b58a3.js +0 -0
  373. {ui → pycharter/ui}/static/static/static/_next/static/chunks/652ad0aa26265c47.js +0 -0
  374. {ui → pycharter/ui/static}/static/static/_next/static/chunks/75d88a058d8ffaa6.js +0 -0
  375. {ui → pycharter/ui/static}/static/static/_next/static/chunks/8c89634cf6bad76f.js +0 -0
  376. {ui → pycharter/ui/static}/static/static/_next/static/chunks/9667e7a3d359eb39.js +0 -0
  377. {ui → pycharter/ui}/static/static/static/_next/static/chunks/9c23f44fff36548a.js +0 -0
  378. {ui → pycharter/ui}/static/static/static/_next/static/chunks/a6dad97d9634a72d.js +0 -0
  379. {ui → pycharter/ui}/static/static/static/_next/static/chunks/b32a0963684b9933.js +0 -0
  380. {ui → pycharter/ui/static}/static/static/_next/static/chunks/c4fa4f4114b7c352.js +0 -0
  381. {ui → pycharter/ui/static}/static/static/_next/static/chunks/c69f6cba366bd988.js +0 -0
  382. {ui → pycharter/ui/static}/static/static/_next/static/chunks/d2363397e1b2bcab.css +0 -0
  383. {ui → pycharter/ui}/static/static/static/_next/static/chunks/db913959c675cea6.js +0 -0
  384. {ui → pycharter/ui/static}/static/static/_next/static/chunks/f061a4be97bfc3b3.js +0 -0
  385. {ui → pycharter/ui}/static/static/static/_next/static/chunks/f2e7afeab1178138.js +0 -0
  386. {ui → pycharter/ui}/static/static/static/_next/static/chunks/ff1a16fafef87110.js +0 -0
  387. {ui → pycharter/ui}/static/static/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +0 -0
  388. {ui → pycharter/ui/static}/static/static/_not-found/__next._full.txt +0 -0
  389. {ui → pycharter/ui/static}/static/static/_not-found/__next._head.txt +0 -0
  390. {ui → pycharter/ui/static}/static/static/_not-found/__next._index.txt +0 -0
  391. {ui → pycharter/ui/static}/static/static/_not-found/__next._not-found.__PAGE__.txt +0 -0
  392. {ui → pycharter/ui/static}/static/static/_not-found/__next._not-found.txt +0 -0
  393. {ui → pycharter/ui/static}/static/static/_not-found/__next._tree.txt +0 -0
  394. {ui → pycharter/ui/static}/static/static/_not-found/index.html +0 -0
  395. {ui → pycharter/ui/static}/static/static/_not-found/index.txt +0 -0
  396. {ui → pycharter/ui/static}/static/static/contracts/__next._full.txt +0 -0
  397. {ui → pycharter/ui/static}/static/static/contracts/__next._head.txt +0 -0
  398. {ui → pycharter/ui/static}/static/static/contracts/__next._index.txt +0 -0
  399. {ui → pycharter/ui/static}/static/static/contracts/__next._tree.txt +0 -0
  400. {ui → pycharter/ui/static}/static/static/contracts/__next.contracts.__PAGE__.txt +0 -0
  401. {ui → pycharter/ui/static}/static/static/contracts/__next.contracts.txt +0 -0
  402. {ui → pycharter/ui/static}/static/static/contracts/index.html +0 -0
  403. {ui → pycharter/ui/static}/static/static/contracts/index.txt +0 -0
  404. {ui → pycharter/ui/static}/static/static/documentation/__next._full.txt +0 -0
  405. {ui → pycharter/ui/static}/static/static/documentation/__next._head.txt +0 -0
  406. {ui → pycharter/ui/static}/static/static/documentation/__next._index.txt +0 -0
  407. {ui → pycharter/ui/static}/static/static/documentation/__next._tree.txt +0 -0
  408. {ui → pycharter/ui/static}/static/static/documentation/__next.documentation.__PAGE__.txt +0 -0
  409. {ui → pycharter/ui/static}/static/static/documentation/__next.documentation.txt +0 -0
  410. {ui → pycharter/ui/static}/static/static/documentation/index.html +0 -0
  411. {ui → pycharter/ui/static}/static/static/documentation/index.txt +0 -0
  412. {ui → pycharter/ui/static}/static/static/index.html +0 -0
  413. {ui → pycharter/ui/static}/static/static/index.txt +0 -0
  414. {ui → pycharter/ui/static}/static/static/metadata/__next._full.txt +0 -0
  415. {ui → pycharter/ui/static}/static/static/metadata/__next._head.txt +0 -0
  416. {ui → pycharter/ui/static}/static/static/metadata/__next._index.txt +0 -0
  417. {ui → pycharter/ui/static}/static/static/metadata/__next._tree.txt +0 -0
  418. {ui → pycharter/ui/static}/static/static/metadata/__next.metadata.__PAGE__.txt +0 -0
  419. {ui → pycharter/ui/static}/static/static/metadata/__next.metadata.txt +0 -0
  420. {ui → pycharter/ui/static}/static/static/metadata/index.html +0 -0
  421. {ui → pycharter/ui/static}/static/static/metadata/index.txt +0 -0
  422. {ui → pycharter/ui/static}/static/static/quality/__next._full.txt +0 -0
  423. {ui → pycharter/ui/static}/static/static/quality/__next._head.txt +0 -0
  424. {ui → pycharter/ui/static}/static/static/quality/__next._index.txt +0 -0
  425. {ui → pycharter/ui/static}/static/static/quality/__next._tree.txt +0 -0
  426. {ui → pycharter/ui/static}/static/static/quality/__next.quality.__PAGE__.txt +0 -0
  427. {ui → pycharter/ui/static}/static/static/quality/__next.quality.txt +0 -0
  428. {ui → pycharter/ui/static}/static/static/quality/index.html +0 -0
  429. {ui → pycharter/ui/static}/static/static/quality/index.txt +0 -0
  430. {ui → pycharter/ui/static}/static/static/rules/__next._full.txt +0 -0
  431. {ui → pycharter/ui/static}/static/static/rules/__next._head.txt +0 -0
  432. {ui → pycharter/ui/static}/static/static/rules/__next._index.txt +0 -0
  433. {ui → pycharter/ui/static}/static/static/rules/__next._tree.txt +0 -0
  434. {ui → pycharter/ui/static}/static/static/rules/__next.rules.__PAGE__.txt +0 -0
  435. {ui → pycharter/ui/static}/static/static/rules/__next.rules.txt +0 -0
  436. {ui → pycharter/ui/static}/static/static/rules/index.html +0 -0
  437. {ui → pycharter/ui/static}/static/static/rules/index.txt +0 -0
  438. {ui → pycharter/ui/static}/static/static/schemas/__next._full.txt +0 -0
  439. {ui → pycharter/ui/static}/static/static/schemas/__next._head.txt +0 -0
  440. {ui → pycharter/ui/static}/static/static/schemas/__next._index.txt +0 -0
  441. {ui → pycharter/ui/static}/static/static/schemas/__next._tree.txt +0 -0
  442. {ui → pycharter/ui/static}/static/static/schemas/__next.schemas.__PAGE__.txt +0 -0
  443. {ui → pycharter/ui/static}/static/static/schemas/__next.schemas.txt +0 -0
  444. {ui → pycharter/ui/static}/static/static/schemas/index.html +0 -0
  445. {ui → pycharter/ui/static}/static/static/schemas/index.txt +0 -0
  446. {ui → pycharter/ui/static}/static/static/settings/__next._full.txt +0 -0
  447. {ui → pycharter/ui/static}/static/static/settings/__next._head.txt +0 -0
  448. {ui → pycharter/ui/static}/static/static/settings/__next._index.txt +0 -0
  449. {ui → pycharter/ui/static}/static/static/settings/__next._tree.txt +0 -0
  450. {ui → pycharter/ui/static}/static/static/settings/__next.settings.__PAGE__.txt +0 -0
  451. {ui → pycharter/ui/static}/static/static/settings/__next.settings.txt +0 -0
  452. {ui → pycharter/ui/static}/static/static/settings/index.html +0 -0
  453. {ui → pycharter/ui/static}/static/static/settings/index.txt +0 -0
  454. {ui → pycharter/ui/static}/static/static/static/404/index.html +0 -0
  455. {ui → pycharter/ui/static}/static/static/static/404.html +0 -0
  456. {ui → pycharter/ui/static}/static/static/static/__next.__PAGE__.txt +0 -0
  457. {ui → pycharter/ui/static}/static/static/static/__next._full.txt +0 -0
  458. {ui → pycharter/ui/static}/static/static/static/__next._head.txt +0 -0
  459. {ui → pycharter/ui/static}/static/static/static/__next._index.txt +0 -0
  460. {ui → pycharter/ui/static}/static/static/static/__next._tree.txt +0 -0
  461. {ui → pycharter/ui/static}/static/static/static/_next/static/chunks/2ab439ce003cd691.js +0 -0
  462. {ui → pycharter/ui/static}/static/static/static/_next/static/chunks/49ca65abd26ae49e.js +0 -0
  463. {ui → pycharter/ui/static}/static/static/static/_next/static/chunks/4e310fe5005770a3.css +0 -0
  464. {ui → pycharter/ui/static}/static/static/static/_next/static/chunks/5e04d10c4a7b58a3.js +0 -0
  465. {ui → pycharter/ui/static}/static/static/static/_next/static/chunks/5fc14c00a2779dc5.js +0 -0
  466. {ui → pycharter/ui/static}/static/static/static/_next/static/chunks/75d88a058d8ffaa6.js +0 -0
  467. {ui → pycharter/ui/static}/static/static/static/_next/static/chunks/8c89634cf6bad76f.js +0 -0
  468. {ui → pycharter/ui/static}/static/static/static/_next/static/chunks/9667e7a3d359eb39.js +0 -0
  469. {ui → pycharter/ui/static}/static/static/static/_next/static/chunks/b584574fdc8ab13e.js +0 -0
  470. {ui → pycharter/ui/static}/static/static/static/_next/static/chunks/c69f6cba366bd988.js +0 -0
  471. {ui → pycharter/ui/static}/static/static/static/_next/static/chunks/d5989c94d3614b3a.js +0 -0
  472. {ui → pycharter/ui/static}/static/static/static/_next/static/chunks/f061a4be97bfc3b3.js +0 -0
  473. {ui → pycharter/ui/static}/static/static/static/_not-found/__next._full.txt +0 -0
  474. {ui → pycharter/ui/static}/static/static/static/_not-found/__next._head.txt +0 -0
  475. {ui → pycharter/ui/static}/static/static/static/_not-found/__next._index.txt +0 -0
  476. {ui → pycharter/ui/static}/static/static/static/_not-found/__next._not-found.__PAGE__.txt +0 -0
  477. {ui → pycharter/ui/static}/static/static/static/_not-found/__next._not-found.txt +0 -0
  478. {ui → pycharter/ui/static}/static/static/static/_not-found/__next._tree.txt +0 -0
  479. {ui → pycharter/ui/static}/static/static/static/_not-found/index.html +0 -0
  480. {ui → pycharter/ui/static}/static/static/static/_not-found/index.txt +0 -0
  481. {ui → pycharter/ui/static}/static/static/static/contracts/__next._full.txt +0 -0
  482. {ui → pycharter/ui/static}/static/static/static/contracts/__next._head.txt +0 -0
  483. {ui → pycharter/ui/static}/static/static/static/contracts/__next._index.txt +0 -0
  484. {ui → pycharter/ui/static}/static/static/static/contracts/__next._tree.txt +0 -0
  485. {ui → pycharter/ui/static}/static/static/static/contracts/__next.contracts.__PAGE__.txt +0 -0
  486. {ui → pycharter/ui/static}/static/static/static/contracts/__next.contracts.txt +0 -0
  487. {ui → pycharter/ui/static}/static/static/static/contracts/index.html +0 -0
  488. {ui → pycharter/ui/static}/static/static/static/contracts/index.txt +0 -0
  489. {ui → pycharter/ui/static}/static/static/static/documentation/__next._full.txt +0 -0
  490. {ui → pycharter/ui/static}/static/static/static/documentation/__next._head.txt +0 -0
  491. {ui → pycharter/ui/static}/static/static/static/documentation/__next._index.txt +0 -0
  492. {ui → pycharter/ui/static}/static/static/static/documentation/__next._tree.txt +0 -0
  493. {ui → pycharter/ui/static}/static/static/static/documentation/__next.documentation.__PAGE__.txt +0 -0
  494. {ui → pycharter/ui/static}/static/static/static/documentation/__next.documentation.txt +0 -0
  495. {ui → pycharter/ui/static}/static/static/static/documentation/index.html +0 -0
  496. {ui → pycharter/ui/static}/static/static/static/documentation/index.txt +0 -0
  497. {ui → pycharter/ui/static}/static/static/static/index.html +0 -0
  498. {ui → pycharter/ui/static}/static/static/static/index.txt +0 -0
  499. {ui → pycharter/ui/static}/static/static/static/metadata/__next._full.txt +0 -0
  500. {ui → pycharter/ui/static}/static/static/static/metadata/__next._head.txt +0 -0
  501. {ui → pycharter/ui/static}/static/static/static/metadata/__next._index.txt +0 -0
  502. {ui → pycharter/ui/static}/static/static/static/metadata/__next._tree.txt +0 -0
  503. {ui → pycharter/ui/static}/static/static/static/metadata/__next.metadata.__PAGE__.txt +0 -0
  504. {ui → pycharter/ui/static}/static/static/static/metadata/__next.metadata.txt +0 -0
  505. {ui → pycharter/ui/static}/static/static/static/metadata/index.html +0 -0
  506. {ui → pycharter/ui/static}/static/static/static/metadata/index.txt +0 -0
  507. {ui → pycharter/ui/static}/static/static/static/quality/__next._full.txt +0 -0
  508. {ui → pycharter/ui/static}/static/static/static/quality/__next._head.txt +0 -0
  509. {ui → pycharter/ui/static}/static/static/static/quality/__next._index.txt +0 -0
  510. {ui → pycharter/ui/static}/static/static/static/quality/__next._tree.txt +0 -0
  511. {ui → pycharter/ui/static}/static/static/static/quality/__next.quality.__PAGE__.txt +0 -0
  512. {ui → pycharter/ui/static}/static/static/static/quality/__next.quality.txt +0 -0
  513. {ui → pycharter/ui/static}/static/static/static/quality/index.html +0 -0
  514. {ui → pycharter/ui/static}/static/static/static/quality/index.txt +0 -0
  515. {ui → pycharter/ui/static}/static/static/static/rules/__next._full.txt +0 -0
  516. {ui → pycharter/ui/static}/static/static/static/rules/__next._head.txt +0 -0
  517. {ui → pycharter/ui/static}/static/static/static/rules/__next._index.txt +0 -0
  518. {ui → pycharter/ui/static}/static/static/static/rules/__next._tree.txt +0 -0
  519. {ui → pycharter/ui/static}/static/static/static/rules/__next.rules.__PAGE__.txt +0 -0
  520. {ui → pycharter/ui/static}/static/static/static/rules/__next.rules.txt +0 -0
  521. {ui → pycharter/ui/static}/static/static/static/rules/index.html +0 -0
  522. {ui → pycharter/ui/static}/static/static/static/rules/index.txt +0 -0
  523. {ui → pycharter/ui/static}/static/static/static/schemas/__next._full.txt +0 -0
  524. {ui → pycharter/ui/static}/static/static/static/schemas/__next._head.txt +0 -0
  525. {ui → pycharter/ui/static}/static/static/static/schemas/__next._index.txt +0 -0
  526. {ui → pycharter/ui/static}/static/static/static/schemas/__next._tree.txt +0 -0
  527. {ui → pycharter/ui/static}/static/static/static/schemas/__next.schemas.__PAGE__.txt +0 -0
  528. {ui → pycharter/ui/static}/static/static/static/schemas/__next.schemas.txt +0 -0
  529. {ui → pycharter/ui/static}/static/static/static/schemas/index.html +0 -0
  530. {ui → pycharter/ui/static}/static/static/static/schemas/index.txt +0 -0
  531. {ui → pycharter/ui/static}/static/static/static/settings/__next._full.txt +0 -0
  532. {ui → pycharter/ui/static}/static/static/static/settings/__next._head.txt +0 -0
  533. {ui → pycharter/ui/static}/static/static/static/settings/__next._index.txt +0 -0
  534. {ui → pycharter/ui/static}/static/static/static/settings/__next._tree.txt +0 -0
  535. {ui → pycharter/ui/static}/static/static/static/settings/__next.settings.__PAGE__.txt +0 -0
  536. {ui → pycharter/ui/static}/static/static/static/settings/__next.settings.txt +0 -0
  537. {ui → pycharter/ui/static}/static/static/static/settings/index.html +0 -0
  538. {ui → pycharter/ui/static}/static/static/static/settings/index.txt +0 -0
  539. {ui → pycharter/ui/static}/static/static/static/validation/__next._full.txt +0 -0
  540. {ui → pycharter/ui/static}/static/static/static/validation/__next._head.txt +0 -0
  541. {ui → pycharter/ui/static}/static/static/static/validation/__next._index.txt +0 -0
  542. {ui → pycharter/ui/static}/static/static/static/validation/__next._tree.txt +0 -0
  543. {ui → pycharter/ui/static}/static/static/static/validation/__next.validation.__PAGE__.txt +0 -0
  544. {ui → pycharter/ui/static}/static/static/static/validation/__next.validation.txt +0 -0
  545. {ui → pycharter/ui/static}/static/static/static/validation/index.html +0 -0
  546. {ui → pycharter/ui/static}/static/static/static/validation/index.txt +0 -0
  547. {ui → pycharter/ui/static}/static/static/validation/__next._full.txt +0 -0
  548. {ui → pycharter/ui/static}/static/static/validation/__next._head.txt +0 -0
  549. {ui → pycharter/ui/static}/static/static/validation/__next._index.txt +0 -0
  550. {ui → pycharter/ui/static}/static/static/validation/__next._tree.txt +0 -0
  551. {ui → pycharter/ui/static}/static/static/validation/__next.validation.__PAGE__.txt +0 -0
  552. {ui → pycharter/ui/static}/static/static/validation/__next.validation.txt +0 -0
  553. {ui → pycharter/ui/static}/static/static/validation/index.html +0 -0
  554. {ui → pycharter/ui/static}/static/static/validation/index.txt +0 -0
  555. {ui → pycharter/ui/static}/static/validation/__next._full.txt +0 -0
  556. {ui → pycharter/ui/static}/static/validation/__next._head.txt +0 -0
  557. {ui → pycharter/ui/static}/static/validation/__next._index.txt +0 -0
  558. {ui → pycharter/ui/static}/static/validation/__next._tree.txt +0 -0
  559. {ui → pycharter/ui/static}/static/validation/__next.validation.__PAGE__.txt +0 -0
  560. {ui → pycharter/ui/static}/static/validation/__next.validation.txt +0 -0
  561. {ui → pycharter/ui/static}/static/validation/index.html +0 -0
  562. {ui → pycharter/ui/static}/static/validation/index.txt +0 -0
  563. {worker → pycharter/worker}/__init__.py +0 -0
  564. {worker → pycharter/worker}/models.py +0 -0
  565. {pycharter-0.0.24.dist-info → pycharter-0.0.26.dist-info}/WHEEL +0 -0
  566. {pycharter-0.0.24.dist-info → pycharter-0.0.26.dist-info}/entry_points.txt +0 -0
  567. {pycharter-0.0.24.dist-info → pycharter-0.0.26.dist-info}/licenses/LICENSE +0 -0
@@ -2,33 +2,27 @@
2
2
  Configuration validation for ETL pipelines.
3
3
 
4
4
  Provides validation of extract, transform, and load configurations
5
- with clear, actionable error messages.
5
+ using Pydantic models with clear, actionable error messages.
6
6
  """
7
7
 
8
- import json
9
- from pathlib import Path
10
- from typing import Any, Dict, List, Optional, Tuple, Union
8
+ from typing import Any, Dict, List, Optional, Tuple
11
9
 
12
- try:
13
- import jsonschema
14
- from jsonschema import Draft7Validator, ValidationError as JsonschemaValidationError
15
- HAS_JSONSCHEMA = True
16
- except ImportError:
17
- HAS_JSONSCHEMA = False
18
- JsonschemaValidationError = Exception # type: ignore[misc, assignment]
10
+ from pydantic import ValidationError as PydanticValidationError
19
11
 
20
12
  from pycharter.shared.errors import ConfigValidationError
21
- from pycharter.etl_generator.schemas import (
22
- get_extract_schema,
23
- get_transform_schema,
24
- get_load_schema,
25
- get_pipeline_schema,
13
+ from pycharter.etl_generator.config_models import (
14
+ parse_extract_config,
15
+ parse_load_config,
16
+ parse_transform_config,
17
+ parse_settings_config,
18
+ SettingsConfig,
19
+ TransformConfig,
26
20
  )
27
21
 
28
22
 
29
23
  class ConfigValidator:
30
24
  """
31
- Validates ETL pipeline configurations against JSON schemas.
25
+ Validates ETL pipeline configurations using Pydantic models.
32
26
 
33
27
  Provides clear error messages to help users fix configuration issues.
34
28
 
@@ -56,146 +50,80 @@ class ConfigValidator:
56
50
  If False, return errors without raising.
57
51
  """
58
52
  self.strict = strict
59
- self._extract_schema = None
60
- self._transform_schema = None
61
- self._load_schema = None
62
- self._pipeline_schema = None
63
53
 
64
- @property
65
- def extract_schema(self) -> Dict[str, Any]:
66
- if self._extract_schema is None:
67
- self._extract_schema = get_extract_schema()
68
- return self._extract_schema
69
-
70
- @property
71
- def transform_schema(self) -> Dict[str, Any]:
72
- if self._transform_schema is None:
73
- self._transform_schema = get_transform_schema()
74
- return self._transform_schema
75
-
76
- @property
77
- def load_schema(self) -> Dict[str, Any]:
78
- if self._load_schema is None:
79
- self._load_schema = get_load_schema()
80
- return self._load_schema
81
-
82
- @property
83
- def pipeline_schema(self) -> Dict[str, Any]:
84
- if self._pipeline_schema is None:
85
- self._pipeline_schema = get_pipeline_schema()
86
- return self._pipeline_schema
87
-
88
- def _validate(
89
- self,
90
- config: Dict[str, Any],
91
- schema: Dict[str, Any],
92
- config_type: str,
93
- config_path: Optional[str] = None,
94
- ) -> Tuple[bool, List[Dict[str, Any]]]:
95
- """
96
- Validate config against schema.
97
-
98
- Returns:
99
- Tuple of (is_valid, list of error dicts)
100
- """
101
- if not HAS_JSONSCHEMA:
102
- # If jsonschema not installed, do basic validation
103
- return self._basic_validate(config, config_type)
104
-
105
- errors = []
106
- validator = Draft7Validator(schema)
107
-
108
- for error in sorted(validator.iter_errors(config), key=lambda e: str(e.path)):
109
- error_dict = {
110
- "path": ".".join(str(p) for p in error.absolute_path) or "(root)",
111
- "message": self._format_error_message(error, config_type),
112
- "validator": error.validator,
113
- "schema_path": list(error.schema_path),
114
- }
115
- errors.append(error_dict)
116
-
117
- return len(errors) == 0, errors
118
-
119
- def _basic_validate(
54
+ def _format_pydantic_errors(
120
55
  self,
121
- config: Dict[str, Any],
56
+ error: PydanticValidationError,
122
57
  config_type: str,
123
- ) -> Tuple[bool, List[Dict[str, Any]]]:
124
- """Basic validation without jsonschema library."""
58
+ ) -> List[Dict[str, Any]]:
59
+ """Convert Pydantic validation errors to our format."""
125
60
  errors = []
126
-
127
- if config_type == "extract":
128
- if "type" not in config:
129
- errors.append({
130
- "path": "type",
131
- "message": "Missing required field 'type'. Must be one of: http, file, database, cloud_storage",
132
- })
133
- elif config["type"] not in ("http", "file", "database", "cloud_storage"):
134
- errors.append({
135
- "path": "type",
136
- "message": f"Invalid type '{config['type']}'. Must be one of: http, file, database, cloud_storage",
137
- })
138
-
139
- elif config_type == "load":
140
- if "type" not in config:
141
- errors.append({
142
- "path": "type",
143
- "message": "Missing required field 'type'. Must be one of: postgres, sqlite, file, cloud_storage",
144
- })
145
- elif config["type"] not in ("postgres", "postgresql", "sqlite", "database", "file", "cloud_storage"):
146
- errors.append({
147
- "path": "type",
148
- "message": f"Invalid type '{config['type']}'. Must be one of: postgres, sqlite, file, cloud_storage",
149
- })
150
-
151
- elif config_type == "pipeline":
152
- if "extract" not in config:
153
- errors.append({
154
- "path": "extract",
155
- "message": "Missing required section 'extract'",
156
- })
157
- if "load" not in config:
158
- errors.append({
159
- "path": "load",
160
- "message": "Missing required section 'load'",
161
- })
162
-
163
- return len(errors) == 0, errors
61
+ for err in error.errors():
62
+ path = ".".join(str(p) for p in err["loc"]) or "(root)"
63
+ errors.append({
64
+ "path": path,
65
+ "message": self._format_error_message(err, config_type),
66
+ "type": err["type"],
67
+ })
68
+ return errors
164
69
 
165
- def _format_error_message(self, error: JsonschemaValidationError, config_type: str) -> str:
166
- """Format a validation error into a user-friendly message."""
167
- msg = error.message
70
+ def _format_error_message(self, error: Dict[str, Any], config_type: str) -> str:
71
+ """Format a Pydantic error into a user-friendly message."""
72
+ error_type = error["type"]
73
+ msg = error["msg"]
168
74
 
169
75
  # Improve common error messages
170
- if error.validator == "required":
171
- missing = list(error.validator_value)
172
- if "type" in missing:
76
+ if error_type == "missing":
77
+ field = error["loc"][-1] if error["loc"] else "unknown"
78
+ if field == "type":
173
79
  valid_types = {
174
80
  "extract": "http, file, database, cloud_storage",
175
- "load": "postgres, sqlite, file, cloud_storage",
81
+ "load": "postgres, postgresql, sqlite, file, cloud_storage",
176
82
  }
177
83
  types = valid_types.get(config_type, "")
178
84
  if types:
179
85
  return f"Missing required 'type' field. Must be one of: {types}"
180
- return f"Missing required field(s): {', '.join(missing)}"
86
+ return f"Missing required field: {field}"
181
87
 
182
- elif error.validator == "enum":
183
- allowed = error.validator_value
184
- return f"Invalid value. Allowed values: {', '.join(str(v) for v in allowed)}"
88
+ elif error_type == "enum":
89
+ # Extract allowed values from the input
90
+ ctx = error.get("ctx", {})
91
+ expected = ctx.get("expected", "")
92
+ return f"Invalid value. Allowed values: {expected}"
185
93
 
186
- elif error.validator == "type":
187
- expected = error.validator_value
188
- actual = type(error.instance).__name__
189
- return f"Expected {expected}, got {actual}"
94
+ elif error_type in ("string_type", "int_type", "float_type", "bool_type"):
95
+ expected = error_type.replace("_type", "")
96
+ return f"Expected {expected}"
190
97
 
191
- elif error.validator == "anyOf":
192
- return "Config doesn't match any of the allowed patterns"
98
+ elif error_type == "extra_forbidden":
99
+ field = error["loc"][-1] if error["loc"] else "unknown"
100
+ return f"Unknown field: '{field}'"
193
101
 
194
- elif error.validator == "oneOf":
195
- return "Config must match exactly one of the allowed patterns"
102
+ elif error_type == "value_error":
103
+ return str(msg)
196
104
 
197
105
  return msg
198
106
 
107
+ def _validate_with_pydantic(
108
+ self,
109
+ config: Dict[str, Any],
110
+ config_type: str,
111
+ parse_func,
112
+ ) -> Tuple[bool, List[Dict[str, Any]]]:
113
+ """Validate config using Pydantic model."""
114
+ try:
115
+ parse_func(config)
116
+ return True, []
117
+ except PydanticValidationError as e:
118
+ return False, self._format_pydantic_errors(e, config_type)
119
+ except ValueError as e:
120
+ # Handle parse_* function ValueErrors (e.g., unknown type)
121
+ return False, [{
122
+ "path": "(root)",
123
+ "message": str(e),
124
+ "type": "value_error",
125
+ }]
126
+
199
127
  def validate_extract(
200
128
  self,
201
129
  config: Dict[str, Any],
@@ -211,11 +139,13 @@ class ConfigValidator:
211
139
  Raises:
212
140
  ConfigValidationError: If validation fails and strict=True
213
141
  """
214
- is_valid, errors = self._validate(config, self.extract_schema, "extract", config_path)
142
+ is_valid, errors = self._validate_with_pydantic(
143
+ config, "extract", parse_extract_config
144
+ )
215
145
 
216
146
  if not is_valid and self.strict:
217
147
  raise ConfigValidationError(
218
- f"Invalid extract configuration",
148
+ "Invalid extract configuration",
219
149
  errors=errors,
220
150
  config_type="extract",
221
151
  config_path=config_path,
@@ -240,11 +170,13 @@ class ConfigValidator:
240
170
  if not config:
241
171
  return
242
172
 
243
- is_valid, errors = self._validate(config, self.transform_schema, "transform", config_path)
173
+ is_valid, errors = self._validate_with_pydantic(
174
+ config, "transform", lambda c: TransformConfig(**c)
175
+ )
244
176
 
245
177
  if not is_valid and self.strict:
246
178
  raise ConfigValidationError(
247
- f"Invalid transform configuration",
179
+ "Invalid transform configuration",
248
180
  errors=errors,
249
181
  config_type="transform",
250
182
  config_path=config_path,
@@ -265,16 +197,45 @@ class ConfigValidator:
265
197
  Raises:
266
198
  ConfigValidationError: If validation fails and strict=True
267
199
  """
268
- is_valid, errors = self._validate(config, self.load_schema, "load", config_path)
200
+ is_valid, errors = self._validate_with_pydantic(
201
+ config, "load", parse_load_config
202
+ )
269
203
 
270
204
  if not is_valid and self.strict:
271
205
  raise ConfigValidationError(
272
- f"Invalid load configuration",
206
+ "Invalid load configuration",
273
207
  errors=errors,
274
208
  config_type="load",
275
209
  config_path=config_path,
276
210
  )
277
211
 
212
+ def validate_settings(
213
+ self,
214
+ config: Dict[str, Any],
215
+ config_path: Optional[str] = None,
216
+ ) -> None:
217
+ """
218
+ Validate settings configuration.
219
+
220
+ Args:
221
+ config: Settings configuration dict
222
+ config_path: Optional path to config file (for error messages)
223
+
224
+ Raises:
225
+ ConfigValidationError: If validation fails and strict=True
226
+ """
227
+ is_valid, errors = self._validate_with_pydantic(
228
+ config, "settings", parse_settings_config
229
+ )
230
+
231
+ if not is_valid and self.strict:
232
+ raise ConfigValidationError(
233
+ "Invalid settings configuration",
234
+ errors=errors,
235
+ config_type="settings",
236
+ config_path=config_path,
237
+ )
238
+
278
239
  def validate_pipeline(
279
240
  self,
280
241
  config: Dict[str, Any],
@@ -290,47 +251,50 @@ class ConfigValidator:
290
251
  Raises:
291
252
  ConfigValidationError: If validation fails and strict=True
292
253
  """
293
- # Basic structure validation
294
254
  errors = []
295
255
 
256
+ # Validate extract (required)
296
257
  if "extract" not in config:
297
258
  errors.append({
298
259
  "path": "extract",
299
260
  "message": "Missing required 'extract' section",
261
+ "type": "missing",
300
262
  })
301
263
  else:
302
- is_valid, extract_errors = self._validate(
303
- config["extract"], self.extract_schema, "extract"
264
+ is_valid, extract_errors = self._validate_with_pydantic(
265
+ config["extract"], "extract", parse_extract_config
304
266
  )
305
267
  for e in extract_errors:
306
268
  e["path"] = f"extract.{e['path']}" if e["path"] != "(root)" else "extract"
307
269
  errors.extend(extract_errors)
308
270
 
271
+ # Validate transform (optional)
309
272
  if "transform" in config and config["transform"]:
310
- # Validate transform if present
311
273
  transform_config = config["transform"]
312
- # If transform is directly the operations (list or dict), wrap it
274
+ # Wrap if it's just simple ops
313
275
  if isinstance(transform_config, (list, dict)):
314
276
  if isinstance(transform_config, list) or not any(
315
277
  k in transform_config for k in ("transform", "jsonata", "custom_function")
316
278
  ):
317
279
  transform_config = {"transform": transform_config}
318
280
 
319
- is_valid, transform_errors = self._validate(
320
- transform_config, self.transform_schema, "transform"
281
+ is_valid, transform_errors = self._validate_with_pydantic(
282
+ transform_config, "transform", lambda c: TransformConfig(**c)
321
283
  )
322
284
  for e in transform_errors:
323
285
  e["path"] = f"transform.{e['path']}" if e["path"] != "(root)" else "transform"
324
286
  errors.extend(transform_errors)
325
287
 
288
+ # Validate load (required)
326
289
  if "load" not in config:
327
290
  errors.append({
328
291
  "path": "load",
329
292
  "message": "Missing required 'load' section",
293
+ "type": "missing",
330
294
  })
331
295
  else:
332
- is_valid, load_errors = self._validate(
333
- config["load"], self.load_schema, "load"
296
+ is_valid, load_errors = self._validate_with_pydantic(
297
+ config["load"], "load", parse_load_config
334
298
  )
335
299
  for e in load_errors:
336
300
  e["path"] = f"load.{e['path']}" if e["path"] != "(root)" else "load"
@@ -338,7 +302,7 @@ class ConfigValidator:
338
302
 
339
303
  if errors and self.strict:
340
304
  raise ConfigValidationError(
341
- f"Invalid pipeline configuration",
305
+ "Invalid pipeline configuration",
342
306
  errors=errors,
343
307
  config_type="pipeline",
344
308
  config_path=config_path,
@@ -349,7 +313,7 @@ class ConfigValidator:
349
313
  config: Dict[str, Any],
350
314
  ) -> Tuple[bool, List[Dict[str, Any]]]:
351
315
  """Check extract config without raising. Returns (is_valid, errors)."""
352
- return self._validate(config, self.extract_schema, "extract")
316
+ return self._validate_with_pydantic(config, "extract", parse_extract_config)
353
317
 
354
318
  def check_transform(
355
319
  self,
@@ -358,14 +322,23 @@ class ConfigValidator:
358
322
  """Check transform config without raising. Returns (is_valid, errors)."""
359
323
  if not config:
360
324
  return True, []
361
- return self._validate(config, self.transform_schema, "transform")
325
+ return self._validate_with_pydantic(
326
+ config, "transform", lambda c: TransformConfig(**c)
327
+ )
362
328
 
363
329
  def check_load(
364
330
  self,
365
331
  config: Dict[str, Any],
366
332
  ) -> Tuple[bool, List[Dict[str, Any]]]:
367
333
  """Check load config without raising. Returns (is_valid, errors)."""
368
- return self._validate(config, self.load_schema, "load")
334
+ return self._validate_with_pydantic(config, "load", parse_load_config)
335
+
336
+ def check_settings(
337
+ self,
338
+ config: Dict[str, Any],
339
+ ) -> Tuple[bool, List[Dict[str, Any]]]:
340
+ """Check settings config without raising. Returns (is_valid, errors)."""
341
+ return self._validate_with_pydantic(config, "settings", parse_settings_config)
369
342
 
370
343
 
371
344
  def validate_config(
@@ -379,7 +352,7 @@ def validate_config(
379
352
 
380
353
  Args:
381
354
  config: Configuration dict
382
- config_type: One of "extract", "transform", "load", "pipeline"
355
+ config_type: One of "extract", "transform", "load", "settings", "pipeline"
383
356
  config_path: Optional path to config file
384
357
  strict: If True, raise on validation failure
385
358
 
@@ -400,6 +373,9 @@ def validate_config(
400
373
  elif config_type == "load":
401
374
  validator.validate_load(config, config_path)
402
375
  return validator.check_load(config)
376
+ elif config_type == "settings":
377
+ validator.validate_settings(config, config_path)
378
+ return validator.check_settings(config)
403
379
  elif config_type == "pipeline":
404
380
  validator.validate_pipeline(config, config_path)
405
381
  # Return combined check
@@ -10,8 +10,11 @@ from dataclasses import dataclass, field
10
10
  from typing import Any, Dict, Optional
11
11
 
12
12
  # Variable pattern: ${VAR_NAME} or ${VAR_NAME:-default} or ${VAR_NAME:?error}
13
+ # This is the canonical definition - import from here in other modules
13
14
  VARIABLE_PATTERN = re.compile(r'\$\{([^}:]+)(?::([?-])([^}]*))?\}')
14
15
 
16
+ __all__ = ["PipelineContext", "VARIABLE_PATTERN"]
17
+
15
18
 
16
19
  @dataclass
17
20
  class PipelineContext:
@@ -39,6 +39,7 @@ DB_MYSQL = "mysql"
39
39
  DB_SQLITE = "sqlite"
40
40
  DB_MSSQL = "mssql"
41
41
  DB_ORACLE = "oracle"
42
+ DB_MONGODB = "mongodb"
42
43
 
43
44
  # Default ports for SSH tunnel
44
45
  DEFAULT_POSTGRES_PORT = 5432
@@ -86,10 +87,13 @@ def detect_database_type(db_url: str) -> str:
86
87
  # Check for Oracle
87
88
  elif base_url.startswith("oracle://"):
88
89
  return DB_ORACLE
90
+ # Check for MongoDB
91
+ elif base_url.startswith(("mongodb://", "mongodb+srv://")):
92
+ return DB_MONGODB
89
93
  else:
90
94
  raise ValueError(
91
95
  f"Cannot detect database type from connection string. "
92
- f"Supported formats: postgresql://, mysql://, sqlite://, mssql://, oracle:// "
96
+ f"Supported formats: postgresql://, mysql://, sqlite://, mssql://, oracle://, mongodb:// "
93
97
  f"(async variants like postgresql+asyncpg:// are also supported). "
94
98
  f"Got: {db_url[:50]}..."
95
99
  )
@@ -5,6 +5,7 @@ This module provides a modular architecture for data extraction from various sou
5
5
  - HTTP/API extraction
6
6
  - File-based extraction (CSV, JSON, Parquet, Excel, TSV, XML)
7
7
  - Database extraction (PostgreSQL, MySQL, SQLite, MSSQL, Oracle)
8
+ - MongoDB extraction (queries and aggregation pipelines)
8
9
  - Cloud storage extraction (S3, GCS, Azure Blob)
9
10
 
10
11
  Entry point for orchestration: extract_with_pagination_streaming().
@@ -14,17 +15,18 @@ from pycharter.etl_generator.extractors.base import BaseExtractor
14
15
  from pycharter.etl_generator.extractors.cloud_storage import CloudStorageExtractor
15
16
  from pycharter.etl_generator.extractors.database import DatabaseExtractor
16
17
  from pycharter.etl_generator.extractors.file import FileExtractor
17
- from pycharter.etl_generator.extractors.factory import ExtractorFactory, get_extractor
18
+ from pycharter.etl_generator.extractors.factory import ExtractorFactory
18
19
  from pycharter.etl_generator.extractors.http import HTTPExtractor
20
+ from pycharter.etl_generator.extractors.mongodb import MongoDBExtractor
19
21
  from pycharter.etl_generator.extractors.streaming import extract_with_pagination_streaming
20
22
 
21
23
  __all__ = [
22
24
  "BaseExtractor",
23
25
  "ExtractorFactory",
24
- "get_extractor",
25
26
  "HTTPExtractor",
26
27
  "FileExtractor",
27
28
  "DatabaseExtractor",
29
+ "MongoDBExtractor",
28
30
  "CloudStorageExtractor",
29
31
  "extract_with_pagination_streaming",
30
32
  ]
@@ -125,10 +125,10 @@ class CloudStorageExtractor(BaseExtractor):
125
125
 
126
126
  def validate_config(self, extract_config: Dict[str, Any]) -> None:
127
127
  """Validate cloud storage extractor configuration."""
128
- if 'source_type' in extract_config and extract_config['source_type'] != 'cloud_storage':
128
+ if 'type' in extract_config and extract_config['type'] != 'cloud_storage':
129
129
  raise ValueError(
130
- f"CloudStorageExtractor requires source_type='cloud_storage', "
131
- f"got '{extract_config.get('source_type')}'"
130
+ f"CloudStorageExtractor requires type='cloud_storage', "
131
+ f"got '{extract_config.get('type')}'"
132
132
  )
133
133
 
134
134
  storage_config = extract_config.get('storage', {})
@@ -266,7 +266,7 @@ class CloudStorageExtractor(BaseExtractor):
266
266
  # Use FileExtractor to process the file
267
267
  file_extractor = FileExtractor()
268
268
  file_config = {
269
- 'source_type': 'file',
269
+ 'type': 'file',
270
270
  'file_path': str(tmp_path),
271
271
  'format': file_format,
272
272
  }
@@ -292,7 +292,7 @@ class CloudStorageExtractor(BaseExtractor):
292
292
  # Use FileExtractor to process the file
293
293
  file_extractor = FileExtractor()
294
294
  file_config = {
295
- 'source_type': 'file',
295
+ 'type': 'file',
296
296
  'file_path': str(tmp_path),
297
297
  'format': file_format,
298
298
  }
@@ -369,7 +369,7 @@ class CloudStorageExtractor(BaseExtractor):
369
369
  # Use FileExtractor
370
370
  file_extractor = FileExtractor()
371
371
  file_config = {
372
- 'source_type': 'file',
372
+ 'type': 'file',
373
373
  'file_path': str(tmp_path),
374
374
  'format': file_format,
375
375
  }
@@ -395,7 +395,7 @@ class CloudStorageExtractor(BaseExtractor):
395
395
  # Use FileExtractor
396
396
  file_extractor = FileExtractor()
397
397
  file_config = {
398
- 'source_type': 'file',
398
+ 'type': 'file',
399
399
  'file_path': str(tmp_path),
400
400
  'format': file_format,
401
401
  }
@@ -473,7 +473,7 @@ class CloudStorageExtractor(BaseExtractor):
473
473
  # Use FileExtractor
474
474
  file_extractor = FileExtractor()
475
475
  file_config = {
476
- 'source_type': 'file',
476
+ 'type': 'file',
477
477
  'file_path': str(tmp_path),
478
478
  'format': file_format,
479
479
  }
@@ -500,7 +500,7 @@ class CloudStorageExtractor(BaseExtractor):
500
500
  # Use FileExtractor
501
501
  file_extractor = FileExtractor()
502
502
  file_config = {
503
- 'source_type': 'file',
503
+ 'type': 'file',
504
504
  'file_path': str(tmp_path),
505
505
  'format': file_format,
506
506
  }
@@ -102,8 +102,8 @@ class DatabaseExtractor(BaseExtractor):
102
102
 
103
103
  def validate_config(self, extract_config: Dict[str, Any]) -> None:
104
104
  """Validate database extractor configuration."""
105
- if 'source_type' in extract_config and extract_config['source_type'] != 'database':
106
- raise ValueError(f"DatabaseExtractor requires source_type='database', got '{extract_config.get('source_type')}'")
105
+ if 'type' in extract_config and extract_config['type'] != 'database':
106
+ raise ValueError(f"DatabaseExtractor requires type='database', got '{extract_config.get('type')}'")
107
107
 
108
108
  db_config = extract_config.get('database', {})
109
109
  if not db_config.get('url'):