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
@@ -0,0 +1,91 @@
1
+ # Async and Execution Model
2
+
3
+ This document describes how PyCharter's ETL pipeline uses async execution, where the event loop runs, and how to run pipelines from scripts and long-running applications.
4
+
5
+ ## Pipeline execution is async
6
+
7
+ The `Pipeline.run()` method is **async** and returns a coroutine. Extractors yield batches asynchronously, and loaders perform I/O asynchronously. You must run the pipeline within an event loop.
8
+
9
+ ## Running a pipeline
10
+
11
+ ### From a script (one-off run)
12
+
13
+ Use `asyncio.run()` to run the pipeline. This creates an event loop, runs the pipeline, and closes the loop when done.
14
+
15
+ ```python
16
+ import asyncio
17
+ from pycharter import Pipeline
18
+
19
+ async def main():
20
+ pipeline = Pipeline.from_config_dir("pipelines/users/")
21
+ result = await pipeline.run()
22
+ print(f"Loaded {result.rows_loaded} rows")
23
+
24
+ if __name__ == "__main__":
25
+ asyncio.run(main())
26
+ ```
27
+
28
+ **Important:** Call `asyncio.run(main())` only once per process. Do not nest `asyncio.run()` calls.
29
+
30
+ ### From an async application (FastAPI, Celery async, etc.)
31
+
32
+ If you are already inside an async context (e.g. a FastAPI route or an async Celery task), **await** the pipeline directly. Do not use `asyncio.run()` — it would create a new event loop and can conflict with the existing one.
33
+
34
+ ```python
35
+ from fastapi import APIRouter
36
+ from pycharter import Pipeline
37
+
38
+ router = APIRouter()
39
+
40
+ @router.post("/run-etl")
41
+ async def run_etl():
42
+ pipeline = Pipeline.from_config_dir("pipelines/users/")
43
+ result = await pipeline.run()
44
+ return {"rows_loaded": result.rows_loaded}
45
+ ```
46
+
47
+ ### Where the event loop runs
48
+
49
+ | Context | Event loop | How to run the pipeline |
50
+ |---------------------------|-------------------------------|------------------------------|
51
+ | Script (e.g. `python run.py`) | Created by `asyncio.run()` | `asyncio.run(main())` |
52
+ | Jupyter / IPython | Built-in loop | `await pipeline.run()` |
53
+ | FastAPI / Starlette | Uvicorn’s loop | `await pipeline.run()` |
54
+ | Async Celery task | Worker’s loop | `await pipeline.run()` |
55
+ | Sync code (no loop) | None | Use `asyncio.run(main())` |
56
+
57
+ ## Error handling and error mode
58
+
59
+ `Pipeline.run()` accepts an optional `error_context` (from `pycharter.shared.errors`). The default error context’s mode controls whether failures **raise** or are **collected**:
60
+
61
+ - **STRICT (default for many paths):** Extraction or load failures raise exceptions. Use when you want fail-fast behavior.
62
+ - **LENIENT:** Failures are logged and appended to `result.errors`; the pipeline continues where possible.
63
+ - **COLLECT:** Same as lenient but errors are also collected on the context for later inspection.
64
+
65
+ ```python
66
+ from pycharter import Pipeline
67
+ from pycharter.shared.errors import get_error_context, set_error_mode, ErrorMode
68
+
69
+ # Optional: set global mode (e.g. lenient for a script)
70
+ set_error_mode(ErrorMode.LENIENT)
71
+
72
+ pipeline = Pipeline.from_config_dir("pipelines/users/")
73
+ result = await pipeline.run()
74
+
75
+ if not result.success:
76
+ for err in result.errors:
77
+ print(err)
78
+ ```
79
+
80
+ You can also pass a specific `ErrorContext` into `run()` instead of using the global default:
81
+
82
+ ```python
83
+ from pycharter.shared.errors import ErrorContext, ErrorMode
84
+
85
+ ctx = ErrorContext(mode=ErrorMode.LENIENT)
86
+ result = await pipeline.run(error_context=ctx)
87
+ ```
88
+
89
+ ## No async context manager (yet)
90
+
91
+ The pipeline does not provide an `async with` context manager. Connections (e.g. DB, HTTP) are managed inside the extractor and loader. For cleanup, instantiate and run the pipeline in a scope where you control resource lifetime, or wrap the run in your own try/finally or async context manager.
@@ -0,0 +1,142 @@
1
+ # ETL Generator — Main Interfaces
2
+
3
+ This document describes the main public interfaces of `pycharter.etl_generator`. Use these when building or extending ETL pipelines.
4
+
5
+ ---
6
+
7
+ ## Primary interface: run pipelines
8
+
9
+ ### `ETLOrchestrator`
10
+
11
+ **Import:** `from pycharter.etl_generator import ETLOrchestrator`
12
+
13
+ The main entry point for running ETL. It runs: **Extract → Transform → Load** from contract artifacts and ETL configs (`extract.yaml`, `transform.yaml`, `load.yaml`).
14
+
15
+ - **Constructor:** `ETLOrchestrator(contract_dir=None, contract_file=None, contract_dict=None, contract_metadata=None, checkpoint_dir=None, progress_callback=None, verbose=True, max_memory_mb=None, config_context=None, extract_config=None, transform_config=None, load_config=None, extract_file=None, transform_file=None, load_file=None)`
16
+ - **Main methods:**
17
+ - `run(**kwargs)` → `Dict` — Run the full pipeline (async). Pass `dry_run=True` to transform/load without writing. Input params (e.g. `symbol`, `start_date`) come from `extract.yaml`’s `input_params` and `**kwargs`.
18
+ - `extract_stream(batch_size=None, max_records=None, **kwargs)` → `AsyncIterator[List[Dict]]` — Stream batches from extract only.
19
+ - **Config sources (priority):** direct dict args > file paths > files in `contract_dir`.
20
+
21
+ ### `create_orchestrator(contract_dir=None, **kwargs) -> ETLOrchestrator`
22
+
23
+ **Import:** `from pycharter.etl_generator import create_orchestrator`
24
+
25
+ Factory helper that returns `ETLOrchestrator(contract_dir=contract_dir, **kwargs)`.
26
+
27
+ ---
28
+
29
+ ## Pipeline discovery
30
+
31
+ ### `PipelineFactory`
32
+
33
+ **Import:** `from pycharter.etl_generator import PipelineFactory`
34
+
35
+ Discovers pipelines from a root directory: each subdir that contains `extract.yaml`, `transform.yaml`, and `load.yaml` is treated as one pipeline.
36
+
37
+ - **Constructor:** `PipelineFactory(config_root="configs", excluded_dirs=None, required_files=None)`
38
+ - **Methods:**
39
+ - `get_pipeline_names() -> List[str]`
40
+ - `get_contract_dir(pipeline_name: str) -> Optional[str]`
41
+ - `create_orchestrator(pipeline_name, config_context=None, verbose=True, **orchestrator_kwargs) -> ETLOrchestrator`
42
+ - `refresh()` — Rescan `config_root`
43
+
44
+ ---
45
+
46
+ ## Extract
47
+
48
+ ### `extract_with_pagination_streaming(...) -> AsyncIterator[List[Dict]]`
49
+
50
+ **Import:** `from pycharter.etl_generator.extractors import extract_with_pagination_streaming`
51
+
52
+ Async generator that yields batches of records. Dispatches to the right extractor via `ExtractorFactory` using `type` (or auto-detection from `extract_config`).
53
+
54
+ - **Args:** `extract_config`, `params`, `headers`, `contract_dir=None`, `batch_size=1000`, `max_records=None`, `config_context=None`
55
+
56
+ ### `ExtractorFactory.create(extract_config) -> BaseExtractor`
57
+
58
+ **Import:** `from pycharter.etl_generator.extractors import ExtractorFactory`
59
+
60
+ - `ExtractorFactory.create(extract_config)` — Returns an extractor instance for the given config.
61
+ - **Auto-detection:** `base_url`/`api_endpoint` → http; `file_path` → file; `database` → database; `storage` → cloud_storage.
62
+
63
+ ### Extractors (implementations of `BaseExtractor`)
64
+
65
+ **Import:** `from pycharter.etl_generator.extractors import HTTPExtractor, FileExtractor, DatabaseExtractor, CloudStorageExtractor, BaseExtractor`
66
+
67
+ - **BaseExtractor** — Abstract base. Subclasses implement `validate_config(extract_config)` and `extract_streaming(extract_config, params, headers, contract_dir, batch_size, max_records, config_context)`.
68
+ - **HTTPExtractor** — HTTP/API (single or paginated).
69
+ - **FileExtractor** — Local files (CSV, JSON, Parquet, etc., including glob).
70
+ - **DatabaseExtractor** — SQL over PostgreSQL, MySQL, SQLite, MSSQL, Oracle.
71
+ - **CloudStorageExtractor** — S3, GCS, Azure Blob.
72
+
73
+ Custom extractors: `ExtractorFactory.register(type_name, extractor_class)`.
74
+
75
+ ---
76
+
77
+ ## Transform
78
+
79
+ ### `apply_transforms(data, transform_config, **kwargs) -> List[Dict]`
80
+
81
+ **Import:** `from pycharter.etl_generator.transformers import apply_transforms`
82
+
83
+ Runs the transform pipeline on a list of records. Order: **simple_ops → jsonata → custom_function**. Each step is skipped if not present in config.
84
+
85
+ - **Args:** `data: List[Dict]`, `transform_config: Dict`, plus any `**kwargs` passed to custom functions.
86
+ - **Config shape:** Supports canonical `transform: { rename, convert, defaults, add, select, drop }` and/or top-level `jsonata`, `custom_function`. See `transformers.config.normalize_transform_config` and `pycharter/data/templates/etl/`.
87
+
88
+ ---
89
+
90
+ ## Load
91
+
92
+ ### `load_to_file(data, load_config, ...) -> Dict`
93
+
94
+ **Import:** `from pycharter.etl_generator.loaders import load_to_file`
95
+
96
+ Writes records to a local file. Used when `load_config` has `destination_type: file` (or implies it via `file_path`).
97
+
98
+ - **Args:** `data`, `load_config`, `contract_dir=None`, `config_context=None`
99
+ - **Returns:** `{ "written": n, "total": n }` (and related metadata).
100
+
101
+ ### `load_to_cloud_storage(data, load_config, ...) -> Dict`
102
+
103
+ **Import:** `from pycharter.etl_generator.loaders import load_to_cloud_storage`
104
+
105
+ Writes to S3, GCS, or Azure Blob. Used when `destination_type: cloud_storage` or config has `storage`.
106
+
107
+ - **Args:** `data`, `load_config`, `contract_dir=None`, `config_context=None`
108
+ - **Returns:** `{ "written": n, "total": n }` (and related metadata).
109
+
110
+ Database loading is handled inside the orchestrator via `pycharter.etl_generator.database.load_data` when `destination_type` is omitted or `database` (and `load_config` has `database`, `target_table`, `schema_name`, etc.).
111
+
112
+ ---
113
+
114
+ ## Config generation
115
+
116
+ ### `generate_etl_config(...)` / `generate_etl_config_from_contract(...)` / `generate_etl_config_from_store(...)`
117
+
118
+ **Import:** `from pycharter.etl_generator import generate_etl_config, generate_etl_config_from_contract, generate_etl_config_from_store`
119
+
120
+ Helpers to produce ETL config dicts (extract/transform/load) from contracts or from the metadata store. See docstrings and `config_generator.py` for parameters.
121
+
122
+ ---
123
+
124
+ ## Utilities (progress, checkpoint, DLQ)
125
+
126
+ - **Progress:** `ETLProgress`, `ProgressTracker` — `from pycharter.etl_generator import ETLProgress, ProgressTracker`
127
+ - **Checkpoint/resume:** `CheckpointManager`, `CheckpointState` — `from pycharter.etl_generator import CheckpointManager, CheckpointState`
128
+ - **Dead letter:** `DeadLetterQueue`, `DeadLetterRecord`, `DLQReason` — `from pycharter.etl_generator import DeadLetterQueue, DeadLetterRecord, DLQReason`
129
+
130
+ ---
131
+
132
+ ## Quick reference: import map
133
+
134
+ | Use case | Import |
135
+ |--------------------------|--------|
136
+ | Run ETL | `from pycharter.etl_generator import ETLOrchestrator, create_orchestrator` |
137
+ | Discover pipelines | `from pycharter.etl_generator import PipelineFactory` |
138
+ | Extract (streaming) | `from pycharter.etl_generator.extractors import extract_with_pagination_streaming, ExtractorFactory` |
139
+ | Transform | `from pycharter.etl_generator.transformers import apply_transforms` |
140
+ | Load to file/cloud | `from pycharter.etl_generator.loaders import load_to_file, load_to_cloud_storage` |
141
+ | Config generation | `from pycharter.etl_generator import generate_etl_config, generate_etl_config_from_contract, generate_etl_config_from_store` |
142
+ | Progress / checkpoint/DLQ| `from pycharter.etl_generator import ETLProgress, ProgressTracker, CheckpointManager, CheckpointState, DeadLetterQueue, DeadLetterRecord, DLQReason` |
@@ -0,0 +1,271 @@
1
+ # ETL Orchestrator - User Guide
2
+
3
+ This document describes the ETL Orchestrator features, including simple transformations, JSONata support, and custom functions.
4
+
5
+ ## Transformation Capabilities
6
+
7
+ The ETL orchestrator supports **three levels of transformation complexity**, applied in order:
8
+
9
+ 1. **Simple Operations** (declarative, easy to use) - NEW! ✅
10
+ 2. **JSONata** (powerful query language for complex transformations)
11
+ 3. **Custom Functions** (Python functions for advanced logic)
12
+
13
+ ### Simple Operations (Recommended for Most Use Cases)
14
+
15
+ Simple, declarative operations that handle 90% of transformation needs:
16
+
17
+ ```yaml
18
+ # transform.yaml
19
+ transform:
20
+ rename:
21
+ oldName: new_name
22
+ camelCase: snake_case
23
+ convert:
24
+ price: float
25
+ quantity: integer
26
+ defaults:
27
+ status: "pending"
28
+ add:
29
+ full_name: "${first_name} ${last_name}"
30
+ created_at: "now()"
31
+ select:
32
+ - field1
33
+ - field2
34
+ drop:
35
+ - internal_id
36
+ ```
37
+
38
+ **See [TRANSFORMATION_GUIDE.md](TRANSFORMATION_GUIDE.md) for complete documentation.**
39
+
40
+ ### JSONata (Advanced)
41
+
42
+ Full JSONata support for complex transformations:
43
+
44
+ ```yaml
45
+ jsonata:
46
+ expression: |
47
+ $.{
48
+ "ticker": symbol,
49
+ "avg_price": $average(prices),
50
+ "total_volume": $sum(volumes)
51
+ }
52
+ mode: "batch" # or "record"
53
+ ```
54
+
55
+ ### Custom Functions
56
+
57
+ Import and run external Python modules/functions:
58
+
59
+ ```yaml
60
+ custom_function:
61
+ module: "myproject.transforms"
62
+ function: "optimize_data"
63
+ mode: "batch"
64
+ kwargs:
65
+ method: "min_volatility"
66
+ ```
67
+
68
+ **All three can be used together!** Simple operations → JSONata → Custom functions.
69
+
70
+ ## Enhanced Features
71
+
72
+ ## Features Overview
73
+
74
+ ### Phase 1: Core Streaming Infrastructure ✅
75
+ - **Streaming/Incremental ETL**: Process data in batches (Extract-Batch → Transform-Batch → Load-Batch)
76
+ - **Generator-based Extraction**: Async generators for memory-efficient data extraction
77
+ - **Memory Management**: Automatic memory monitoring and limits
78
+
79
+ ### Phase 2: Observability & Configuration ✅
80
+ - **Configurable Processing Modes**: Choose between `full`, `streaming`, or `hybrid` modes
81
+ - **Progress Tracking**: Real-time progress reporting with callbacks
82
+ - **Error Recovery**: Retry strategies and error threshold management
83
+
84
+ ### Phase 3: Advanced Features ✅
85
+ - **Checkpoint/Resume**: Save and resume long-running jobs
86
+ - **Multiple Runs Support**: Process multiple parameter sets efficiently with rate limiting
87
+
88
+ ## Usage Examples
89
+
90
+ ### Basic Usage (Backward Compatible)
91
+
92
+ ```python
93
+ from pycharter.etl_generator import ETLOrchestrator
94
+
95
+ # Default behavior (full mode) - backward compatible
96
+ orchestrator = ETLOrchestrator(contract_dir="data/examples/my_contract")
97
+ result = await orchestrator.run()
98
+ ```
99
+
100
+ ### Streaming Mode (Memory Efficient)
101
+
102
+ Configure in `extract.yaml`:
103
+ ```yaml
104
+ processing_mode: streaming
105
+ batch_size: 1000
106
+ ```
107
+
108
+ Or use programmatically:
109
+ ```python
110
+ orchestrator = ETLOrchestrator(contract_dir="data/examples/my_contract")
111
+ result = await orchestrator.run_streaming(batch_size=1000)
112
+ ```
113
+
114
+ ### Progress Tracking
115
+
116
+ ```python
117
+ from pycharter.etl_generator import ETLOrchestrator, ETLProgress
118
+
119
+ def log_progress(progress: ETLProgress):
120
+ print(f"{progress}")
121
+
122
+ orchestrator = ETLOrchestrator(
123
+ contract_dir="data/examples/my_contract",
124
+ progress_callback=log_progress,
125
+ verbose=True
126
+ )
127
+ result = await orchestrator.run()
128
+ ```
129
+
130
+ ### Checkpoint/Resume
131
+
132
+ ```python
133
+ orchestrator = ETLOrchestrator(
134
+ contract_dir="data/examples/my_contract",
135
+ checkpoint_dir="./checkpoints"
136
+ )
137
+
138
+ # Run with checkpoint
139
+ result = await orchestrator.run(checkpoint_id="my_job_001")
140
+
141
+ # Resume from checkpoint
142
+ result = await orchestrator.run(
143
+ checkpoint_id="my_job_001",
144
+ resume=True
145
+ )
146
+ ```
147
+
148
+ ### Memory Management
149
+
150
+ ```python
151
+ orchestrator = ETLOrchestrator(
152
+ contract_dir="data/examples/my_contract",
153
+ max_memory_mb=2048 # Limit to 2GB
154
+ )
155
+ result = await orchestrator.run()
156
+ ```
157
+
158
+ ### Multiple Runs Processing
159
+
160
+ Run the same ETL pipeline multiple times with different parameters efficiently:
161
+
162
+ ```python
163
+ orchestrator = ETLOrchestrator(contract_dir="data/examples/my_contract")
164
+
165
+ # Simple case: vary a single parameter (e.g., symbols)
166
+ results = await orchestrator.run_multiple(
167
+ param_name='symbol',
168
+ param_values=["AAPL", "MSFT", "GOOGL", "TSLA"],
169
+ batch_size=5,
170
+ delay_between_runs=1.0
171
+ )
172
+
173
+ for result in results:
174
+ params = result['params']
175
+ print(f"{params}: {result['success']} - {result.get('records', 0)} records")
176
+
177
+ # Complex case: vary multiple parameters
178
+ results = await orchestrator.run_multiple(
179
+ param_sets=[
180
+ {'symbol': 'AAPL', 'date': '2024-01-01'},
181
+ {'symbol': 'MSFT', 'date': '2024-01-02'},
182
+ {'symbol': 'GOOGL', 'date': '2024-01-03'},
183
+ ],
184
+ batch_size=3,
185
+ delay_between_runs=0.5
186
+ )
187
+ ```
188
+
189
+ ### Error Recovery
190
+
191
+ ```python
192
+ result = await orchestrator.run_streaming(
193
+ batch_size=1000,
194
+ max_retries=3,
195
+ error_threshold=0.1 # Abort if >10% of batches fail
196
+ )
197
+ ```
198
+
199
+ ## Configuration Options
200
+
201
+ ### extract.yaml
202
+
203
+ ```yaml
204
+ # Processing mode: 'full', 'streaming', or 'hybrid'
205
+ processing_mode: streaming
206
+
207
+ # Batch size for processing
208
+ batch_size: 1000
209
+
210
+ # Memory limit (optional)
211
+ max_memory_mb: 2048
212
+
213
+ # Checkpoint configuration (optional)
214
+ checkpoint:
215
+ enabled: true
216
+ interval: 100 # Checkpoint every N batches
217
+ ```
218
+
219
+ ## Processing Modes
220
+
221
+ ### Full Mode (Default)
222
+ - **Behavior**: Extract all → Transform all → Load all
223
+ - **Use Case**: Small to medium datasets, backward compatible
224
+ - **Memory**: All data in memory at once
225
+
226
+ ### Streaming Mode
227
+ - **Behavior**: Extract-Batch → Transform-Batch → Load-Batch (incremental)
228
+ - **Use Case**: Large datasets, memory-constrained environments
229
+ - **Memory**: Constant memory usage (batch size)
230
+
231
+ ### Hybrid Mode
232
+ - **Behavior**: Extract in chunks, transform/load in batches
233
+ - **Use Case**: Fast extraction but slow transformation/loading
234
+ - **Memory**: Moderate memory usage
235
+
236
+ ## Architecture
237
+
238
+ ### New Modules
239
+
240
+ - **`progress.py`**: Progress tracking and observability
241
+ - **`checkpoint.py`**: Checkpoint/resume functionality
242
+ - **`extractors/`**: Modular extraction (HTTP, file, database, cloud) with streaming entry point `extract_with_pagination_streaming`
243
+ - **`orchestrator.py`**: Enhanced with all new features
244
+
245
+ ### Backward Compatibility
246
+
247
+ All new features are **100% backward compatible**. Existing code continues to work without changes. New features are opt-in via:
248
+ - Configuration in `extract.yaml`
249
+ - Optional constructor parameters
250
+ - New method calls (`run_streaming()`, `run_multiple()`, etc.)
251
+
252
+ ## Performance Considerations
253
+
254
+ ### Memory Usage
255
+ - **Full Mode**: O(n) where n = total records
256
+ - **Streaming Mode**: O(b) where b = batch size
257
+ - **Hybrid Mode**: O(c) where c = chunk size
258
+
259
+ ### Throughput
260
+ - **Full Mode**: Fastest for small datasets (single pass)
261
+ - **Streaming Mode**: Slower but handles unlimited size
262
+ - **Hybrid Mode**: Balanced approach
263
+
264
+ ## Best Practices
265
+
266
+ 1. **Use streaming mode** for datasets > 100K records
267
+ 2. **Enable checkpoints** for jobs expected to run > 1 hour
268
+ 3. **Set memory limits** to prevent OOM crashes
269
+ 4. **Use progress callbacks** for monitoring long-running jobs
270
+ 5. **Configure error thresholds** based on data quality expectations
271
+