pycharter 0.0.23__tar.gz → 0.0.24__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (602) hide show
  1. {pycharter-0.0.23/pycharter.egg-info → pycharter-0.0.24}/PKG-INFO +141 -26
  2. {pycharter-0.0.23 → pycharter-0.0.24}/README.md +140 -25
  3. {pycharter-0.0.23 → pycharter-0.0.24}/api/main.py +27 -1
  4. pycharter-0.0.24/api/models/docs.py +68 -0
  5. pycharter-0.0.24/api/models/evolution.py +117 -0
  6. pycharter-0.0.24/api/models/tracking.py +111 -0
  7. {pycharter-0.0.23 → pycharter-0.0.24}/api/models/validation.py +46 -6
  8. {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/__init__.py +14 -1
  9. pycharter-0.0.24/api/routes/v1/docs.py +187 -0
  10. pycharter-0.0.24/api/routes/v1/evolution.py +337 -0
  11. {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/templates.py +168 -3
  12. pycharter-0.0.24/api/routes/v1/tracking.py +301 -0
  13. {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/validation.py +68 -31
  14. pycharter-0.0.24/pycharter/__init__.py +421 -0
  15. pycharter-0.0.24/pycharter/data/templates/contract/template_coercion_rules.yaml +57 -0
  16. pycharter-0.0.24/pycharter/data/templates/contract/template_contract.yaml +122 -0
  17. pycharter-0.0.24/pycharter/data/templates/contract/template_metadata.yaml +68 -0
  18. pycharter-0.0.24/pycharter/data/templates/contract/template_schema.yaml +100 -0
  19. pycharter-0.0.24/pycharter/data/templates/contract/template_validation_rules.yaml +75 -0
  20. pycharter-0.0.24/pycharter/data/templates/etl/README.md +224 -0
  21. pycharter-0.0.24/pycharter/data/templates/etl/extract_cloud_azure.yaml +24 -0
  22. pycharter-0.0.24/pycharter/data/templates/etl/extract_cloud_gcs.yaml +25 -0
  23. pycharter-0.0.24/pycharter/data/templates/etl/extract_cloud_s3.yaml +30 -0
  24. pycharter-0.0.24/pycharter/data/templates/etl/extract_database.yaml +34 -0
  25. pycharter-0.0.24/pycharter/data/templates/etl/extract_database_ssh.yaml +40 -0
  26. pycharter-0.0.24/pycharter/data/templates/etl/extract_file_csv.yaml +21 -0
  27. pycharter-0.0.24/pycharter/data/templates/etl/extract_file_glob.yaml +25 -0
  28. pycharter-0.0.24/pycharter/data/templates/etl/extract_file_json.yaml +24 -0
  29. pycharter-0.0.24/pycharter/data/templates/etl/extract_file_parquet.yaml +20 -0
  30. pycharter-0.0.24/pycharter/data/templates/etl/extract_http_paginated.yaml +79 -0
  31. pycharter-0.0.24/pycharter/data/templates/etl/extract_http_path_params.yaml +38 -0
  32. pycharter-0.0.24/pycharter/data/templates/etl/extract_http_simple.yaml +62 -0
  33. pycharter-0.0.24/pycharter/data/templates/etl/load_cloud_azure.yaml +24 -0
  34. pycharter-0.0.24/pycharter/data/templates/etl/load_cloud_gcs.yaml +22 -0
  35. pycharter-0.0.24/pycharter/data/templates/etl/load_cloud_s3.yaml +27 -0
  36. pycharter-0.0.24/pycharter/data/templates/etl/load_file.yaml +34 -0
  37. pycharter-0.0.24/pycharter/data/templates/etl/load_insert.yaml +18 -0
  38. pycharter-0.0.24/pycharter/data/templates/etl/load_postgresql.yaml +39 -0
  39. pycharter-0.0.24/pycharter/data/templates/etl/load_sqlite.yaml +21 -0
  40. pycharter-0.0.24/pycharter/data/templates/etl/load_truncate_and_load.yaml +20 -0
  41. pycharter-0.0.24/pycharter/data/templates/etl/load_upsert.yaml +25 -0
  42. pycharter-0.0.24/pycharter/data/templates/etl/load_with_dlq.yaml +34 -0
  43. pycharter-0.0.24/pycharter/data/templates/etl/load_with_ssh_tunnel.yaml +35 -0
  44. pycharter-0.0.24/pycharter/data/templates/etl/pipeline_http_to_db.yaml +75 -0
  45. pycharter-0.0.24/pycharter/data/templates/etl/transform_combined.yaml +48 -0
  46. pycharter-0.0.24/pycharter/data/templates/etl/transform_custom_function.yaml +58 -0
  47. pycharter-0.0.24/pycharter/data/templates/etl/transform_jsonata.yaml +51 -0
  48. pycharter-0.0.24/pycharter/data/templates/etl/transform_simple.yaml +59 -0
  49. pycharter-0.0.24/pycharter/docs_generator/__init__.py +43 -0
  50. pycharter-0.0.24/pycharter/docs_generator/generator.py +465 -0
  51. pycharter-0.0.24/pycharter/docs_generator/renderers.py +247 -0
  52. pycharter-0.0.24/pycharter/etl_generator/__init__.py +182 -0
  53. pycharter-0.0.24/pycharter/etl_generator/builder.py +121 -0
  54. pycharter-0.0.24/pycharter/etl_generator/config_loader.py +394 -0
  55. pycharter-0.0.24/pycharter/etl_generator/config_validator.py +418 -0
  56. pycharter-0.0.24/pycharter/etl_generator/context.py +132 -0
  57. pycharter-0.0.24/pycharter/etl_generator/expression.py +499 -0
  58. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/extractors/__init__.py +4 -0
  59. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/extractors/cloud_storage.py +77 -1
  60. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/extractors/database.py +71 -1
  61. pycharter-0.0.24/pycharter/etl_generator/extractors/factory.py +185 -0
  62. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/extractors/file.py +58 -1
  63. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/extractors/http.py +80 -1
  64. pycharter-0.0.24/pycharter/etl_generator/extractors/streaming.py +57 -0
  65. pycharter-0.0.24/pycharter/etl_generator/loaders/__init__.py +41 -0
  66. pycharter-0.0.24/pycharter/etl_generator/loaders/base.py +35 -0
  67. pycharter-0.0.24/pycharter/etl_generator/loaders/cloud.py +87 -0
  68. pycharter-0.0.24/pycharter/etl_generator/loaders/cloud_storage_loader.py +275 -0
  69. pycharter-0.0.24/pycharter/etl_generator/loaders/database.py +274 -0
  70. pycharter-0.0.24/pycharter/etl_generator/loaders/factory.py +180 -0
  71. pycharter-0.0.24/pycharter/etl_generator/loaders/file.py +72 -0
  72. pycharter-0.0.24/pycharter/etl_generator/loaders/file_loader.py +130 -0
  73. pycharter-0.0.24/pycharter/etl_generator/pipeline.py +743 -0
  74. pycharter-0.0.24/pycharter/etl_generator/protocols.py +54 -0
  75. pycharter-0.0.24/pycharter/etl_generator/result.py +63 -0
  76. pycharter-0.0.24/pycharter/etl_generator/schemas/__init__.py +49 -0
  77. pycharter-0.0.24/pycharter/etl_generator/transformers/__init__.py +49 -0
  78. pycharter-0.0.24/pycharter/etl_generator/transformers/base.py +63 -0
  79. pycharter-0.0.24/pycharter/etl_generator/transformers/config.py +45 -0
  80. pycharter-0.0.24/pycharter/etl_generator/transformers/custom_function.py +101 -0
  81. pycharter-0.0.24/pycharter/etl_generator/transformers/jsonata_transformer.py +56 -0
  82. pycharter-0.0.24/pycharter/etl_generator/transformers/operations.py +218 -0
  83. pycharter-0.0.24/pycharter/etl_generator/transformers/pipeline.py +54 -0
  84. pycharter-0.0.24/pycharter/etl_generator/transformers/simple_operations.py +131 -0
  85. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/quality/__init__.py +25 -0
  86. pycharter-0.0.24/pycharter/quality/tracking/__init__.py +64 -0
  87. pycharter-0.0.24/pycharter/quality/tracking/collector.py +318 -0
  88. pycharter-0.0.24/pycharter/quality/tracking/exporters.py +238 -0
  89. pycharter-0.0.24/pycharter/quality/tracking/models.py +194 -0
  90. pycharter-0.0.24/pycharter/quality/tracking/store.py +385 -0
  91. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/runtime_validator/__init__.py +20 -7
  92. pycharter-0.0.24/pycharter/runtime_validator/builder.py +328 -0
  93. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/runtime_validator/validator.py +311 -7
  94. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/runtime_validator/validator_core.py +61 -0
  95. pycharter-0.0.24/pycharter/schema_evolution/__init__.py +61 -0
  96. pycharter-0.0.24/pycharter/schema_evolution/compatibility.py +270 -0
  97. pycharter-0.0.24/pycharter/schema_evolution/diff.py +496 -0
  98. pycharter-0.0.24/pycharter/schema_evolution/models.py +201 -0
  99. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/__init__.py +56 -0
  100. pycharter-0.0.24/pycharter/shared/errors.py +296 -0
  101. pycharter-0.0.24/pycharter/shared/protocols.py +234 -0
  102. {pycharter-0.0.23 → pycharter-0.0.24/pycharter.egg-info}/PKG-INFO +141 -26
  103. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter.egg-info/SOURCES.txt +51 -6
  104. {pycharter-0.0.23 → pycharter-0.0.24}/pyproject.toml +1 -1
  105. pycharter-0.0.23/pycharter/__init__.py +0 -211
  106. pycharter-0.0.23/pycharter/data/templates/contract/template_coercion_rules.yaml +0 -15
  107. pycharter-0.0.23/pycharter/data/templates/contract/template_contract.yaml +0 -587
  108. pycharter-0.0.23/pycharter/data/templates/contract/template_metadata.yaml +0 -38
  109. pycharter-0.0.23/pycharter/data/templates/contract/template_schema.yaml +0 -22
  110. pycharter-0.0.23/pycharter/data/templates/contract/template_validation_rules.yaml +0 -29
  111. pycharter-0.0.23/pycharter/data/templates/etl/README.md +0 -91
  112. pycharter-0.0.23/pycharter/data/templates/etl/extract_cloud_azure.yaml +0 -23
  113. pycharter-0.0.23/pycharter/data/templates/etl/extract_cloud_gcs.yaml +0 -22
  114. pycharter-0.0.23/pycharter/data/templates/etl/extract_cloud_s3.yaml +0 -24
  115. pycharter-0.0.23/pycharter/data/templates/etl/extract_database.yaml +0 -28
  116. pycharter-0.0.23/pycharter/data/templates/etl/extract_database_ssh.yaml +0 -27
  117. pycharter-0.0.23/pycharter/data/templates/etl/extract_file_csv.yaml +0 -17
  118. pycharter-0.0.23/pycharter/data/templates/etl/extract_file_glob.yaml +0 -17
  119. pycharter-0.0.23/pycharter/data/templates/etl/extract_file_json.yaml +0 -14
  120. pycharter-0.0.23/pycharter/data/templates/etl/extract_file_parquet.yaml +0 -13
  121. pycharter-0.0.23/pycharter/data/templates/etl/extract_http_paginated.yaml +0 -75
  122. pycharter-0.0.23/pycharter/data/templates/etl/extract_http_path_params.yaml +0 -45
  123. pycharter-0.0.23/pycharter/data/templates/etl/extract_http_simple.yaml +0 -52
  124. pycharter-0.0.23/pycharter/data/templates/etl/load_insert.yaml +0 -17
  125. pycharter-0.0.23/pycharter/data/templates/etl/load_postgresql.yaml +0 -17
  126. pycharter-0.0.23/pycharter/data/templates/etl/load_sqlite.yaml +0 -16
  127. pycharter-0.0.23/pycharter/data/templates/etl/load_truncate_and_load.yaml +0 -18
  128. pycharter-0.0.23/pycharter/data/templates/etl/load_upsert.yaml +0 -28
  129. pycharter-0.0.23/pycharter/data/templates/etl/load_with_dlq.yaml +0 -24
  130. pycharter-0.0.23/pycharter/data/templates/etl/load_with_ssh_tunnel.yaml +0 -28
  131. pycharter-0.0.23/pycharter/data/templates/etl/pipeline_http_to_db.yaml +0 -38
  132. pycharter-0.0.23/pycharter/data/templates/etl/transform_combined.yaml +0 -38
  133. pycharter-0.0.23/pycharter/data/templates/etl/transform_custom_function.yaml +0 -18
  134. pycharter-0.0.23/pycharter/data/templates/etl/transform_jsonata.yaml +0 -20
  135. pycharter-0.0.23/pycharter/data/templates/etl/transform_simple.yaml +0 -41
  136. pycharter-0.0.23/pycharter/etl_generator/__init__.py +0 -94
  137. pycharter-0.0.23/pycharter/etl_generator/extraction.py +0 -701
  138. pycharter-0.0.23/pycharter/etl_generator/extractors/factory.py +0 -141
  139. pycharter-0.0.23/pycharter/etl_generator/factory.py +0 -174
  140. pycharter-0.0.23/pycharter/etl_generator/orchestrator.py +0 -1650
  141. pycharter-0.0.23/pycharter/integrations/__init__.py +0 -19
  142. pycharter-0.0.23/pycharter/integrations/kafka.py +0 -178
  143. pycharter-0.0.23/pycharter/integrations/streaming.py +0 -100
  144. {pycharter-0.0.23 → pycharter-0.0.24}/LICENSE +0 -0
  145. {pycharter-0.0.23 → pycharter-0.0.24}/MANIFEST.in +0 -0
  146. {pycharter-0.0.23 → pycharter-0.0.24}/api/__init__.py +0 -0
  147. {pycharter-0.0.23 → pycharter-0.0.24}/api/dependencies/__init__.py +0 -0
  148. {pycharter-0.0.23 → pycharter-0.0.24}/api/dependencies/database.py +0 -0
  149. {pycharter-0.0.23 → pycharter-0.0.24}/api/dependencies/store.py +0 -0
  150. {pycharter-0.0.23 → pycharter-0.0.24}/api/models/__init__.py +0 -0
  151. {pycharter-0.0.23 → pycharter-0.0.24}/api/models/contracts.py +0 -0
  152. {pycharter-0.0.23 → pycharter-0.0.24}/api/models/metadata.py +0 -0
  153. {pycharter-0.0.23 → pycharter-0.0.24}/api/models/metadata_entities.py +0 -0
  154. {pycharter-0.0.23 → pycharter-0.0.24}/api/models/quality.py +0 -0
  155. {pycharter-0.0.23 → pycharter-0.0.24}/api/models/schemas.py +0 -0
  156. {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/__init__.py +0 -0
  157. {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/contracts.py +0 -0
  158. {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/metadata.py +0 -0
  159. {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/quality.py +0 -0
  160. {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/schemas.py +0 -0
  161. {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/settings.py +0 -0
  162. {pycharter-0.0.23 → pycharter-0.0.24}/api/routes/v1/validation_jobs.py +0 -0
  163. {pycharter-0.0.23 → pycharter-0.0.24}/api/utils.py +0 -0
  164. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/cli.py +0 -0
  165. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/config.py +0 -0
  166. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/contract_builder/__init__.py +0 -0
  167. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/contract_builder/builder.py +0 -0
  168. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/contract_parser/__init__.py +0 -0
  169. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/contract_parser/parser.py +0 -0
  170. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/data/__init__.py +0 -0
  171. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/__init__.py +0 -0
  172. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/cli.py +0 -0
  173. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/README +0 -0
  174. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/env.py +0 -0
  175. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/script.py.mako +0 -0
  176. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20250115120000_add_tier2_tier3_entities.py +0 -0
  177. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20251209163657_799b73fe9f6c_initial_schema.py +0 -0
  178. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20251209164144_ae0efda02aa1_initial_schema.py +0 -0
  179. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20251217160146_f9995dc0f4b3_add_quality_tables.py +0 -0
  180. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20251217164915_8b08d78068e3_add_data_version_tracking.py +0 -0
  181. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20260110083000_a1b2c3d4e5f6_add_dead_letter_queue_table.py +0 -0
  182. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20260120000000_add_name_title_validation_constraints.py +0 -0
  183. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20260121000000_remove_artifact_versions_from_data_contracts.py +0 -0
  184. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/20260122000000_change_artifact_unique_constraints_to_title_version.py +0 -0
  185. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/migrations/versions/__init__.py +0 -0
  186. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/__init__.py +0 -0
  187. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/api_endpoint.py +0 -0
  188. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/base.py +0 -0
  189. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/coercion_rule.py +0 -0
  190. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/compliance_framework.py +0 -0
  191. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/data_contract.py +0 -0
  192. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/data_dependency.py +0 -0
  193. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/data_feed.py +0 -0
  194. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/dlq.py +0 -0
  195. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/domain.py +0 -0
  196. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/environment.py +0 -0
  197. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/metadata_record.py +0 -0
  198. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/owner.py +0 -0
  199. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/quality_metric.py +0 -0
  200. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/quality_violation.py +0 -0
  201. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/schema.py +0 -0
  202. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/storage_location.py +0 -0
  203. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/system.py +0 -0
  204. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/tag.py +0 -0
  205. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/models/validation_rule.py +0 -0
  206. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/schemas/.ipynb_checkpoints/data_contract-checkpoint.py +0 -0
  207. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/schemas/__init__.py +0 -0
  208. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/db/schemas/data_contract.py +0 -0
  209. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/checkpoint.py +0 -0
  210. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/config_generator.py +0 -0
  211. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/database.py +0 -0
  212. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/dlq.py +0 -0
  213. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/extractors/base.py +0 -0
  214. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/etl_generator/progress.py +0 -0
  215. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/json_schema_converter/__init__.py +0 -0
  216. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/json_schema_converter/converter.py +0 -0
  217. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/json_schema_converter/reverse_converter.py +0 -0
  218. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/metadata_store/__init__.py +0 -0
  219. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/metadata_store/client.py +0 -0
  220. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/metadata_store/in_memory.py +0 -0
  221. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/metadata_store/mongodb.py +0 -0
  222. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/metadata_store/postgres.py +0 -0
  223. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/metadata_store/redis.py +0 -0
  224. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/metadata_store/sqlite.py +0 -0
  225. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/py.typed +0 -0
  226. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/pydantic_generator/__init__.py +0 -0
  227. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/pydantic_generator/converter.py +0 -0
  228. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/pydantic_generator/generator.py +0 -0
  229. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/quality/check.py +0 -0
  230. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/quality/cli.py +0 -0
  231. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/quality/metrics.py +0 -0
  232. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/quality/models.py +0 -0
  233. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/quality/profiling.py +0 -0
  234. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/quality/violations.py +0 -0
  235. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/runtime_validator/decorators.py +0 -0
  236. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/runtime_validator/utils.py +0 -0
  237. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/runtime_validator/wrappers.py +0 -0
  238. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/coercions/__init__.py +0 -0
  239. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/coercions/builtin.py +0 -0
  240. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/json_schema_support.py +0 -0
  241. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/json_schema_validator.py +0 -0
  242. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/name_validator.py +0 -0
  243. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/schema_parser.py +0 -0
  244. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/schema_resolver.py +0 -0
  245. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/validations/__init__.py +0 -0
  246. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/shared/validations/builtin.py +0 -0
  247. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/utils/__init__.py +0 -0
  248. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/utils/value_injector.py +0 -0
  249. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter/utils/version.py +0 -0
  250. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter.egg-info/dependency_links.txt +0 -0
  251. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter.egg-info/entry_points.txt +0 -0
  252. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter.egg-info/requires.txt +0 -0
  253. {pycharter-0.0.23 → pycharter-0.0.24}/pycharter.egg-info/top_level.txt +0 -0
  254. {pycharter-0.0.23 → pycharter-0.0.24}/setup.cfg +0 -0
  255. {pycharter-0.0.23 → pycharter-0.0.24}/setup.py +0 -0
  256. {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_contract_builder.py +0 -0
  257. {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_contract_parser.py +0 -0
  258. {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_extractors.py +0 -0
  259. {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_integration.py +0 -0
  260. {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_json_schema_compliance.py +0 -0
  261. {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_json_schema_converter.py +0 -0
  262. {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_metadata_stores.py +0 -0
  263. {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_pydantic_generator.py +0 -0
  264. {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_refs_and_definitions.py +0 -0
  265. {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_runtime_validator.py +0 -0
  266. {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_schema_parser.py +0 -0
  267. {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_value_injector.py +0 -0
  268. {pycharter-0.0.23 → pycharter-0.0.24}/tests/test_x_validators.py +0 -0
  269. {pycharter-0.0.23 → pycharter-0.0.24}/ui/__init__.py +0 -0
  270. {pycharter-0.0.23 → pycharter-0.0.24}/ui/build.py +0 -0
  271. {pycharter-0.0.23 → pycharter-0.0.24}/ui/dev.py +0 -0
  272. {pycharter-0.0.23 → pycharter-0.0.24}/ui/server.py +0 -0
  273. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/.gitkeep +0 -0
  274. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/404/index.html +0 -0
  275. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/404.html +0 -0
  276. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/__next.__PAGE__.txt +0 -0
  277. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/__next._full.txt +0 -0
  278. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/__next._head.txt +0 -0
  279. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/__next._index.txt +0 -0
  280. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/__next._tree.txt +0 -0
  281. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/2gKjNv6YvE6BcIdFthBLs/_buildManifest.js +0 -0
  282. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/2gKjNv6YvE6BcIdFthBLs/_ssgManifest.js +0 -0
  283. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/13d4a0fbd74c1ee4.js +0 -0
  284. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/222442f6da32302a.js +0 -0
  285. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/247eb132b7f7b574.js +0 -0
  286. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/26dfc590f7714c03.js +0 -0
  287. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/297d55555b71baba.js +0 -0
  288. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/2ab439ce003cd691.js +0 -0
  289. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/2edb43b48432ac04.js +0 -0
  290. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/34d289e6db2ef551.js +0 -0
  291. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/414e77373f8ff61c.js +0 -0
  292. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/49ca65abd26ae49e.js +0 -0
  293. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/652ad0aa26265c47.js +0 -0
  294. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/9667e7a3d359eb39.js +0 -0
  295. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/99508d9d5869cc27.js +0 -0
  296. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/9c23f44fff36548a.js +0 -0
  297. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/a6dad97d9634a72d.js +0 -0
  298. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/b313c35a6ba76574.js +0 -0
  299. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/b32a0963684b9933.js +0 -0
  300. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/c69f6cba366bd988.js +0 -0
  301. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/d2363397e1b2bcab.css +0 -0
  302. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/db913959c675cea6.js +0 -0
  303. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/f061a4be97bfc3b3.js +0 -0
  304. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/f2e7afeab1178138.js +0 -0
  305. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/f7d1a90dd75d2572.js +0 -0
  306. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/ff1a16fafef87110.js +0 -0
  307. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +0 -0
  308. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/__next._full.txt +0 -0
  309. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/__next._head.txt +0 -0
  310. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/__next._index.txt +0 -0
  311. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/__next._not-found.__PAGE__.txt +0 -0
  312. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/__next._not-found.txt +0 -0
  313. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/__next._tree.txt +0 -0
  314. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/index.html +0 -0
  315. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/_not-found/index.txt +0 -0
  316. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/__next._full.txt +0 -0
  317. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/__next._head.txt +0 -0
  318. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/__next._index.txt +0 -0
  319. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/__next._tree.txt +0 -0
  320. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/__next.contracts.__PAGE__.txt +0 -0
  321. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/__next.contracts.txt +0 -0
  322. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/index.html +0 -0
  323. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/contracts/index.txt +0 -0
  324. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/__next._full.txt +0 -0
  325. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/__next._head.txt +0 -0
  326. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/__next._index.txt +0 -0
  327. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/__next._tree.txt +0 -0
  328. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/__next.documentation.__PAGE__.txt +0 -0
  329. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/__next.documentation.txt +0 -0
  330. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/index.html +0 -0
  331. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/documentation/index.txt +0 -0
  332. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/index.html +0 -0
  333. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/index.txt +0 -0
  334. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/__next._full.txt +0 -0
  335. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/__next._head.txt +0 -0
  336. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/__next._index.txt +0 -0
  337. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/__next._tree.txt +0 -0
  338. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/__next.metadata.__PAGE__.txt +0 -0
  339. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/__next.metadata.txt +0 -0
  340. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/index.html +0 -0
  341. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/metadata/index.txt +0 -0
  342. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/__next._full.txt +0 -0
  343. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/__next._head.txt +0 -0
  344. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/__next._index.txt +0 -0
  345. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/__next._tree.txt +0 -0
  346. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/__next.quality.__PAGE__.txt +0 -0
  347. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/__next.quality.txt +0 -0
  348. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/index.html +0 -0
  349. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/quality/index.txt +0 -0
  350. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/__next._full.txt +0 -0
  351. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/__next._head.txt +0 -0
  352. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/__next._index.txt +0 -0
  353. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/__next._tree.txt +0 -0
  354. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/__next.rules.__PAGE__.txt +0 -0
  355. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/__next.rules.txt +0 -0
  356. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/index.html +0 -0
  357. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/rules/index.txt +0 -0
  358. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/__next._full.txt +0 -0
  359. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/__next._head.txt +0 -0
  360. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/__next._index.txt +0 -0
  361. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/__next._tree.txt +0 -0
  362. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/__next.schemas.__PAGE__.txt +0 -0
  363. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/__next.schemas.txt +0 -0
  364. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/index.html +0 -0
  365. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/schemas/index.txt +0 -0
  366. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/__next._full.txt +0 -0
  367. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/__next._head.txt +0 -0
  368. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/__next._index.txt +0 -0
  369. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/__next._tree.txt +0 -0
  370. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/__next.settings.__PAGE__.txt +0 -0
  371. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/__next.settings.txt +0 -0
  372. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/index.html +0 -0
  373. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/settings/index.txt +0 -0
  374. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/.gitkeep +0 -0
  375. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/404/index.html +0 -0
  376. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/404.html +0 -0
  377. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/__next.__PAGE__.txt +0 -0
  378. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/__next._full.txt +0 -0
  379. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/__next._head.txt +0 -0
  380. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/__next._index.txt +0 -0
  381. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/__next._tree.txt +0 -0
  382. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/0rYA78L88aUyD2Uh38hhX/_buildManifest.js +0 -0
  383. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/0rYA78L88aUyD2Uh38hhX/_ssgManifest.js +0 -0
  384. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/13d4a0fbd74c1ee4.js +0 -0
  385. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/222442f6da32302a.js +0 -0
  386. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/247eb132b7f7b574.js +0 -0
  387. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/297d55555b71baba.js +0 -0
  388. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/2ab439ce003cd691.js +0 -0
  389. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/2edb43b48432ac04.js +0 -0
  390. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/414e77373f8ff61c.js +0 -0
  391. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/49ca65abd26ae49e.js +0 -0
  392. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/5e04d10c4a7b58a3.js +0 -0
  393. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/652ad0aa26265c47.js +0 -0
  394. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/75d88a058d8ffaa6.js +0 -0
  395. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/8c89634cf6bad76f.js +0 -0
  396. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/9667e7a3d359eb39.js +0 -0
  397. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/9c23f44fff36548a.js +0 -0
  398. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/a6dad97d9634a72d.js +0 -0
  399. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/b32a0963684b9933.js +0 -0
  400. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/c4fa4f4114b7c352.js +0 -0
  401. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/c69f6cba366bd988.js +0 -0
  402. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/d2363397e1b2bcab.css +0 -0
  403. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/db913959c675cea6.js +0 -0
  404. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/f061a4be97bfc3b3.js +0 -0
  405. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/f2e7afeab1178138.js +0 -0
  406. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/f7d1a90dd75d2572.js +0 -0
  407. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/ff1a16fafef87110.js +0 -0
  408. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +0 -0
  409. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/__next._full.txt +0 -0
  410. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/__next._head.txt +0 -0
  411. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/__next._index.txt +0 -0
  412. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/__next._not-found.__PAGE__.txt +0 -0
  413. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/__next._not-found.txt +0 -0
  414. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/__next._tree.txt +0 -0
  415. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/index.html +0 -0
  416. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/_not-found/index.txt +0 -0
  417. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/__next._full.txt +0 -0
  418. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/__next._head.txt +0 -0
  419. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/__next._index.txt +0 -0
  420. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/__next._tree.txt +0 -0
  421. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/__next.contracts.__PAGE__.txt +0 -0
  422. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/__next.contracts.txt +0 -0
  423. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/index.html +0 -0
  424. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/contracts/index.txt +0 -0
  425. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/__next._full.txt +0 -0
  426. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/__next._head.txt +0 -0
  427. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/__next._index.txt +0 -0
  428. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/__next._tree.txt +0 -0
  429. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/__next.documentation.__PAGE__.txt +0 -0
  430. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/__next.documentation.txt +0 -0
  431. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/index.html +0 -0
  432. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/documentation/index.txt +0 -0
  433. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/index.html +0 -0
  434. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/index.txt +0 -0
  435. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/__next._full.txt +0 -0
  436. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/__next._head.txt +0 -0
  437. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/__next._index.txt +0 -0
  438. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/__next._tree.txt +0 -0
  439. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/__next.metadata.__PAGE__.txt +0 -0
  440. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/__next.metadata.txt +0 -0
  441. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/index.html +0 -0
  442. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/metadata/index.txt +0 -0
  443. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/__next._full.txt +0 -0
  444. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/__next._head.txt +0 -0
  445. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/__next._index.txt +0 -0
  446. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/__next._tree.txt +0 -0
  447. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/__next.quality.__PAGE__.txt +0 -0
  448. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/__next.quality.txt +0 -0
  449. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/index.html +0 -0
  450. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/quality/index.txt +0 -0
  451. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/__next._full.txt +0 -0
  452. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/__next._head.txt +0 -0
  453. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/__next._index.txt +0 -0
  454. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/__next._tree.txt +0 -0
  455. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/__next.rules.__PAGE__.txt +0 -0
  456. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/__next.rules.txt +0 -0
  457. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/index.html +0 -0
  458. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/rules/index.txt +0 -0
  459. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/__next._full.txt +0 -0
  460. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/__next._head.txt +0 -0
  461. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/__next._index.txt +0 -0
  462. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/__next._tree.txt +0 -0
  463. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/__next.schemas.__PAGE__.txt +0 -0
  464. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/__next.schemas.txt +0 -0
  465. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/index.html +0 -0
  466. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/schemas/index.txt +0 -0
  467. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/__next._full.txt +0 -0
  468. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/__next._head.txt +0 -0
  469. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/__next._index.txt +0 -0
  470. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/__next._tree.txt +0 -0
  471. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/__next.settings.__PAGE__.txt +0 -0
  472. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/__next.settings.txt +0 -0
  473. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/index.html +0 -0
  474. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/settings/index.txt +0 -0
  475. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/.gitkeep +0 -0
  476. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/404/index.html +0 -0
  477. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/404.html +0 -0
  478. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/__next.__PAGE__.txt +0 -0
  479. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/__next._full.txt +0 -0
  480. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/__next._head.txt +0 -0
  481. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/__next._index.txt +0 -0
  482. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/__next._tree.txt +0 -0
  483. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/222442f6da32302a.js +0 -0
  484. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/247eb132b7f7b574.js +0 -0
  485. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/297d55555b71baba.js +0 -0
  486. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/2ab439ce003cd691.js +0 -0
  487. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/414e77373f8ff61c.js +0 -0
  488. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/49ca65abd26ae49e.js +0 -0
  489. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/4e310fe5005770a3.css +0 -0
  490. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/5e04d10c4a7b58a3.js +0 -0
  491. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/5fc14c00a2779dc5.js +0 -0
  492. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/652ad0aa26265c47.js +0 -0
  493. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/75d88a058d8ffaa6.js +0 -0
  494. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/8c89634cf6bad76f.js +0 -0
  495. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/9667e7a3d359eb39.js +0 -0
  496. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/9c23f44fff36548a.js +0 -0
  497. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/a6dad97d9634a72d.js +0 -0
  498. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/b32a0963684b9933.js +0 -0
  499. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/b584574fdc8ab13e.js +0 -0
  500. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/c69f6cba366bd988.js +0 -0
  501. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/d5989c94d3614b3a.js +0 -0
  502. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/db913959c675cea6.js +0 -0
  503. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/f061a4be97bfc3b3.js +0 -0
  504. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/f2e7afeab1178138.js +0 -0
  505. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/ff1a16fafef87110.js +0 -0
  506. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +0 -0
  507. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_buildManifest.js +0 -0
  508. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_ssgManifest.js +0 -0
  509. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/__next._full.txt +0 -0
  510. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/__next._head.txt +0 -0
  511. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/__next._index.txt +0 -0
  512. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/__next._not-found.__PAGE__.txt +0 -0
  513. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/__next._not-found.txt +0 -0
  514. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/__next._tree.txt +0 -0
  515. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/index.html +0 -0
  516. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/_not-found/index.txt +0 -0
  517. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/__next._full.txt +0 -0
  518. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/__next._head.txt +0 -0
  519. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/__next._index.txt +0 -0
  520. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/__next._tree.txt +0 -0
  521. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/__next.contracts.__PAGE__.txt +0 -0
  522. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/__next.contracts.txt +0 -0
  523. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/index.html +0 -0
  524. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/contracts/index.txt +0 -0
  525. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/__next._full.txt +0 -0
  526. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/__next._head.txt +0 -0
  527. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/__next._index.txt +0 -0
  528. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/__next._tree.txt +0 -0
  529. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/__next.documentation.__PAGE__.txt +0 -0
  530. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/__next.documentation.txt +0 -0
  531. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/index.html +0 -0
  532. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/documentation/index.txt +0 -0
  533. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/index.html +0 -0
  534. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/index.txt +0 -0
  535. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/__next._full.txt +0 -0
  536. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/__next._head.txt +0 -0
  537. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/__next._index.txt +0 -0
  538. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/__next._tree.txt +0 -0
  539. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/__next.metadata.__PAGE__.txt +0 -0
  540. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/__next.metadata.txt +0 -0
  541. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/index.html +0 -0
  542. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/metadata/index.txt +0 -0
  543. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/__next._full.txt +0 -0
  544. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/__next._head.txt +0 -0
  545. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/__next._index.txt +0 -0
  546. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/__next._tree.txt +0 -0
  547. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/__next.quality.__PAGE__.txt +0 -0
  548. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/__next.quality.txt +0 -0
  549. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/index.html +0 -0
  550. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/quality/index.txt +0 -0
  551. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/__next._full.txt +0 -0
  552. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/__next._head.txt +0 -0
  553. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/__next._index.txt +0 -0
  554. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/__next._tree.txt +0 -0
  555. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/__next.rules.__PAGE__.txt +0 -0
  556. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/__next.rules.txt +0 -0
  557. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/index.html +0 -0
  558. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/rules/index.txt +0 -0
  559. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/__next._full.txt +0 -0
  560. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/__next._head.txt +0 -0
  561. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/__next._index.txt +0 -0
  562. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/__next._tree.txt +0 -0
  563. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/__next.schemas.__PAGE__.txt +0 -0
  564. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/__next.schemas.txt +0 -0
  565. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/index.html +0 -0
  566. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/schemas/index.txt +0 -0
  567. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/__next._full.txt +0 -0
  568. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/__next._head.txt +0 -0
  569. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/__next._index.txt +0 -0
  570. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/__next._tree.txt +0 -0
  571. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/__next.settings.__PAGE__.txt +0 -0
  572. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/__next.settings.txt +0 -0
  573. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/index.html +0 -0
  574. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/settings/index.txt +0 -0
  575. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/__next._full.txt +0 -0
  576. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/__next._head.txt +0 -0
  577. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/__next._index.txt +0 -0
  578. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/__next._tree.txt +0 -0
  579. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/__next.validation.__PAGE__.txt +0 -0
  580. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/__next.validation.txt +0 -0
  581. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/index.html +0 -0
  582. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/static/validation/index.txt +0 -0
  583. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/__next._full.txt +0 -0
  584. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/__next._head.txt +0 -0
  585. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/__next._index.txt +0 -0
  586. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/__next._tree.txt +0 -0
  587. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/__next.validation.__PAGE__.txt +0 -0
  588. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/__next.validation.txt +0 -0
  589. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/index.html +0 -0
  590. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/static/validation/index.txt +0 -0
  591. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/__next._full.txt +0 -0
  592. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/__next._head.txt +0 -0
  593. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/__next._index.txt +0 -0
  594. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/__next._tree.txt +0 -0
  595. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/__next.validation.__PAGE__.txt +0 -0
  596. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/__next.validation.txt +0 -0
  597. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/index.html +0 -0
  598. {pycharter-0.0.23 → pycharter-0.0.24}/ui/static/validation/index.txt +0 -0
  599. {pycharter-0.0.23 → pycharter-0.0.24}/worker/__init__.py +0 -0
  600. {pycharter-0.0.23 → pycharter-0.0.24}/worker/cli.py +0 -0
  601. {pycharter-0.0.23 → pycharter-0.0.24}/worker/models.py +0 -0
  602. {pycharter-0.0.23 → pycharter-0.0.24}/worker/processor.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pycharter
3
- Version: 0.0.23
3
+ Version: 0.0.24
4
4
  Summary: A Python package for data contract management with five core services: contract parsing, metadata storage, Pydantic generation, JSON Schema conversion, and runtime validation
5
5
  Author-email: semantic developers <na@example.com>
6
6
  License-Expression: MIT
@@ -164,6 +164,41 @@ pycharter ui dev # Development mode with hot reload
164
164
 
165
165
  ## 🚀 Quick Start
166
166
 
167
+ ### Quick Start: ETL Pipelines
168
+
169
+ Build and run ETL pipelines programmatically (with the `|` operator) or from YAML configs. Pipeline **run()** is async; use `asyncio.run()` from scripts or `await` in async code.
170
+
171
+ ```python
172
+ import asyncio
173
+ from pycharter import Pipeline, HTTPExtractor, PostgresLoader, Rename, AddField
174
+
175
+ # Programmatic pipeline
176
+ pipeline = (
177
+ Pipeline(HTTPExtractor(url="https://api.example.com/data"))
178
+ | Rename({"old": "new"})
179
+ | AddField("processed_at", "now()")
180
+ | PostgresLoader(connection_string="...", table="users")
181
+ )
182
+ result = asyncio.run(pipeline.run())
183
+
184
+ # Config-driven: explicit files
185
+ pipeline = Pipeline.from_config_files(
186
+ extract="configs/extract.yaml",
187
+ load="configs/load.yaml",
188
+ variables={"API_KEY": "secret"}
189
+ )
190
+
191
+ # Config-driven: directory (extract.yaml, transform.yaml, load.yaml)
192
+ pipeline = Pipeline.from_config_dir("pipelines/users/")
193
+
194
+ # Config-driven: single file
195
+ pipeline = Pipeline.from_config_file("pipelines/users/pipeline.yaml")
196
+
197
+ result = asyncio.run(pipeline.run())
198
+ ```
199
+
200
+ See **ETL Pipelines** under Core Services for error handling (`error_context`, `ErrorMode`) and variable resolution (`PipelineContext(variables={...})`).
201
+
167
202
  ### Quick Start: Convenience Functions (One-off Use)
168
203
 
169
204
  ```python
@@ -192,14 +227,29 @@ if result.is_valid:
192
227
 
193
228
  ### Production Use: Validator Class (Recommended)
194
229
 
195
- For production code with multiple validations, use the `Validator` class for better performance:
230
+ For production code with multiple validations, use the `Validator` class for better performance. Create validators via **factory methods** or from a metadata store:
196
231
 
197
232
  ```python
198
233
  from pycharter import Validator
199
234
 
200
- # Create validator from contract directory or file
201
- validator = Validator(contract_dir="data/contracts/user")
202
- # Or: validator = Validator(contract_file="user_contract.yaml")
235
+ # From directory (expects schema.yaml, coercion_rules.yaml, validation_rules.yaml)
236
+ validator = Validator.from_dir("data/contracts/user")
237
+
238
+ # From explicit files (any filenames)
239
+ validator = Validator.from_files(
240
+ schema="schemas/user.yaml",
241
+ coercion_rules="rules/coercion.yaml",
242
+ validation_rules="rules/validation.yaml"
243
+ )
244
+
245
+ # From a single contract file
246
+ validator = Validator.from_file("user_contract.yaml")
247
+
248
+ # From dictionaries
249
+ validator = Validator.from_dict(schema={...}, coercion_rules={...}, validation_rules={...})
250
+
251
+ # From metadata store (with database)
252
+ validator = Validator(store=store, schema_id="user_schema_v1")
203
253
 
204
254
  # Validate multiple records efficiently (model is cached)
205
255
  result1 = validator.validate({"name": "Alice", "age": 30})
@@ -232,11 +282,12 @@ PyCharter's API is organized into **three tiers** to help you choose the right a
232
282
  ### Tier 1: Primary Interfaces (⭐ Recommended for Production)
233
283
 
234
284
  **Classes** that provide the best performance and most features:
235
- - **`Validator`** - Primary validation interface (use for multiple validations)
285
+ - **`Validator`** - Primary validation interface (use for multiple validations); create via `from_dir()`, `from_files()`, `from_file()`, `from_dict()` or from store
286
+ - **`Pipeline`** - ETL pipeline (programmatic or config-driven); create via `from_config_files()`, `from_config_dir()`, `from_config_file()` or constructor
236
287
  - **`QualityCheck`** - Primary quality assurance interface
237
288
  - **`MetadataStoreClient`** - Base class for metadata stores
238
289
 
239
- **When to use**: Production code, batch processing, when you need to validate multiple records.
290
+ **When to use**: Production code, batch processing, when you need to validate multiple records or run ETL pipelines.
240
291
 
241
292
  ### Tier 2: Convenience Functions (Quick Start)
242
293
 
@@ -530,20 +581,24 @@ PyCharter provides validation through three tiers:
530
581
  ```python
531
582
  from pycharter import Validator, SQLiteMetadataStore
532
583
 
533
- # Option 1: From contract directory (no database)
534
- validator = Validator(contract_dir="data/contracts/user")
584
+ # Option 1: From directory (schema.yaml, coercion_rules.yaml, validation_rules.yaml)
585
+ validator = Validator.from_dir("data/contracts/user")
586
+ result = validator.validate({"name": "Alice", "age": 30})
587
+
588
+ # Option 2: From explicit files
589
+ validator = Validator.from_files(schema="schemas/user.yaml", coercion_rules="rules/coercion.yaml")
590
+ result = validator.validate({"name": "Alice", "age": 30})
591
+
592
+ # Option 3: From single contract file
593
+ validator = Validator.from_file("user_contract.yaml")
535
594
  result = validator.validate({"name": "Alice", "age": 30})
536
595
 
537
- # Option 2: From metadata store (with database)
596
+ # Option 4: From metadata store (with database)
538
597
  store = SQLiteMetadataStore("metadata.db")
539
598
  store.connect()
540
599
  validator = Validator(store=store, schema_id="user_schema_v1")
541
600
  result = validator.validate({"name": "Alice", "age": 30})
542
601
 
543
- # Option 3: From contract file
544
- validator = Validator(contract_file="user_contract.yaml")
545
- result = validator.validate({"name": "Alice", "age": 30})
546
-
547
602
  # Batch validation (efficient - model cached)
548
603
  results = validator.validate_batch([data1, data2, data3])
549
604
  ```
@@ -584,6 +639,55 @@ results = validate_batch(UserModel, [data1, data2, data3])
584
639
 
585
640
  ---
586
641
 
642
+ ### 5b. 🔄 ETL Pipelines (`pycharter.etl_generator`)
643
+
644
+ **Purpose**: Build and run ETL pipelines programmatically (with the `|` operator) or from YAML configs. No assumptions about project layout—you specify file paths or use a directory with standard filenames.
645
+
646
+ **When to Use**: When you need to extract, transform, and load data from config-driven or code-defined pipelines (HTTP, files, databases, cloud storage → transforms → Postgres, files, cloud).
647
+
648
+ **How It Works**:
649
+ - **Programmatic**: `Pipeline(extractor) | transformer | loader`; chain with `|`; call `await pipeline.run()`.
650
+ - **Config-driven**: Load from explicit files (`from_config_files`), from a directory with `extract.yaml`, `transform.yaml`, `load.yaml` (`from_config_dir`), or from a single `pipeline.yaml` (`from_config_file`).
651
+ - **Variables**: Pass `PipelineContext(variables={"API_KEY": "x"})` or `variables={...}` in factory methods; `${VAR}` and `${VAR:-default}` in configs are resolved from these (no built-in `CONTRACT_DIR`).
652
+ - **Async**: `run()` is async; use `asyncio.run(pipeline.run())` in scripts or `await pipeline.run()` in async code.
653
+ - **Error handling**: Optional `error_context` with `ErrorMode` (STRICT, LENIENT, COLLECT) controls whether extraction/load failures raise or are collected in `result.errors`.
654
+
655
+ **Example**:
656
+ ```python
657
+ import asyncio
658
+ from pycharter import Pipeline, PipelineContext, HTTPExtractor, PostgresLoader, Rename, AddField
659
+
660
+ # Programmatic
661
+ pipeline = (
662
+ Pipeline(HTTPExtractor(url="https://api.example.com/users"))
663
+ | Rename({"userName": "name"})
664
+ | AddField("processed_at", "now()")
665
+ | PostgresLoader(connection_string="...", table="users")
666
+ )
667
+ result = asyncio.run(pipeline.run())
668
+
669
+ # Config-driven (explicit files)
670
+ pipeline = Pipeline.from_config_files(
671
+ extract="configs/extract.yaml",
672
+ load="configs/load.yaml",
673
+ variables={"API_KEY": "secret"}
674
+ )
675
+
676
+ # Config-driven (directory: extract.yaml, transform.yaml, load.yaml)
677
+ pipeline = Pipeline.from_config_dir("pipelines/users/")
678
+
679
+ # Config-driven (single file)
680
+ pipeline = Pipeline.from_config_file("pipelines/users/pipeline.yaml")
681
+
682
+ result = asyncio.run(pipeline.run())
683
+ ```
684
+
685
+ **Exceptions**: Pipeline and config loading use PyCharter’s exception hierarchy: `PyCharterError` (base), `ConfigError`, `ConfigValidationError`, `ExpressionError`. See **Exceptions** under API Reference.
686
+
687
+ **See** `pycharter/etl_generator/ASYNC_AND_EXECUTION.md` for async usage and error modes.
688
+
689
+ ---
690
+
587
691
  ### 6. 🔍 Quality Assurance (`pycharter.quality`)
588
692
 
589
693
  **Purpose**: Data quality assurance pipeline that polices data according to data contracts, calculates quality metrics, tracks violations, and generates quality reports.
@@ -704,7 +808,7 @@ def process_user_data_quick(raw_data):
704
808
 
705
809
  ---
706
810
 
707
- ### 7. 🌐 REST API (`api/`)
811
+ ### 7. 🌐 REST API (`api/`) (`api/`)
708
812
 
709
813
  **Purpose**: Expose all PyCharter services as REST API endpoints.
710
814
 
@@ -752,6 +856,7 @@ See `api/README.md` for complete API documentation.
752
856
  | **Pydantic Generator** | JSON Schema | Pydantic models | Storage → Model Generation |
753
857
  | **JSON Schema Converter** | Pydantic models | JSON Schema | (Bidirectional) |
754
858
  | **Runtime Validator** | Pydantic models + Data | `ValidationResult` | Model Generation → Validation |
859
+ | **ETL Pipelines** | Config files or code | `PipelineResult` | Extract → Transform → Load |
755
860
  | **Quality Assurance** | Contract + Data | `QualityReport` | Validation → Quality Monitoring |
756
861
 
757
862
  Each service is designed to be **independent** yet **composable**, allowing you to use them individually or together as part of a complete data contract management system.
@@ -795,12 +900,9 @@ Product = from_file("product_schema.json", "Product")
795
900
  ```python
796
901
  from pycharter import Validator
797
902
 
798
- # From contract directory
799
- validator = Validator(contract_dir="data/contracts/article")
800
- result = validator.validate({"title": "My Article", "published": True})
801
-
802
- # From contract file
803
- validator = Validator(contract_file="article_contract.yaml")
903
+ # From directory or single file
904
+ validator = Validator.from_dir("data/contracts/article")
905
+ # or: validator = Validator.from_file("article_contract.yaml")
804
906
  result = validator.validate({"title": "My Article", "published": True})
805
907
  ```
806
908
 
@@ -1019,11 +1121,12 @@ PyCharter's API is organized into three tiers to help you choose the right appro
1019
1121
  ```python
1020
1122
  from pycharter import Validator
1021
1123
 
1022
- # Create validator from various sources
1023
- validator = Validator(contract_dir="data/contracts/user")
1024
- validator = Validator(contract_file="contract.yaml")
1025
- validator = Validator(store=store, schema_id="user_schema")
1026
- validator = Validator(contract_dict={...})
1124
+ # Create validator via factory methods or store
1125
+ validator = Validator.from_dir("data/contracts/user")
1126
+ validator = Validator.from_files(schema="schema.yaml", coercion_rules="coercion.yaml")
1127
+ validator = Validator.from_file("contract.yaml")
1128
+ validator = Validator.from_dict(schema={...}, coercion_rules={...})
1129
+ validator = Validator(store=store, schema_id="user_schema") # from metadata store
1027
1130
 
1028
1131
  # Validate data
1029
1132
  result = validator.validate(data)
@@ -1094,6 +1197,18 @@ store.connect()
1094
1197
  - **`MongoDBMetadataStore(connection_string: str)`** - MongoDB database
1095
1198
  - **`RedisMetadataStore(connection_string: str)`** - Redis database
1096
1199
 
1200
+ ### Exceptions
1201
+
1202
+ PyCharter uses a small exception hierarchy for config and pipeline errors. Catch **`PyCharterError`** to handle any PyCharter failure:
1203
+
1204
+ - **`PyCharterError`** - Base for all PyCharter exceptions
1205
+ - **`ConfigError`** - Config loading/parsing failures (missing file, invalid YAML)
1206
+ - **`ConfigValidationError`** - Schema validation failures (e.g. missing required `type` field)
1207
+ - **`ConfigLoadError`** - Config file load errors
1208
+ - **`ExpressionError`** - Expression evaluation failures (e.g. invalid syntax in AddField)
1209
+
1210
+ Pipeline **`run(error_context=...)`** supports **`ErrorMode`**: **STRICT** (raise on failure), **LENIENT** (log and continue), **COLLECT** (append to `result.errors`). Import from `pycharter.shared.errors`.
1211
+
1097
1212
  ## 🎯 Design Principles & Requirements
1098
1213
 
1099
1214
  Charter is designed to meet the following core requirements:
@@ -101,6 +101,41 @@ pycharter ui dev # Development mode with hot reload
101
101
 
102
102
  ## 🚀 Quick Start
103
103
 
104
+ ### Quick Start: ETL Pipelines
105
+
106
+ Build and run ETL pipelines programmatically (with the `|` operator) or from YAML configs. Pipeline **run()** is async; use `asyncio.run()` from scripts or `await` in async code.
107
+
108
+ ```python
109
+ import asyncio
110
+ from pycharter import Pipeline, HTTPExtractor, PostgresLoader, Rename, AddField
111
+
112
+ # Programmatic pipeline
113
+ pipeline = (
114
+ Pipeline(HTTPExtractor(url="https://api.example.com/data"))
115
+ | Rename({"old": "new"})
116
+ | AddField("processed_at", "now()")
117
+ | PostgresLoader(connection_string="...", table="users")
118
+ )
119
+ result = asyncio.run(pipeline.run())
120
+
121
+ # Config-driven: explicit files
122
+ pipeline = Pipeline.from_config_files(
123
+ extract="configs/extract.yaml",
124
+ load="configs/load.yaml",
125
+ variables={"API_KEY": "secret"}
126
+ )
127
+
128
+ # Config-driven: directory (extract.yaml, transform.yaml, load.yaml)
129
+ pipeline = Pipeline.from_config_dir("pipelines/users/")
130
+
131
+ # Config-driven: single file
132
+ pipeline = Pipeline.from_config_file("pipelines/users/pipeline.yaml")
133
+
134
+ result = asyncio.run(pipeline.run())
135
+ ```
136
+
137
+ See **ETL Pipelines** under Core Services for error handling (`error_context`, `ErrorMode`) and variable resolution (`PipelineContext(variables={...})`).
138
+
104
139
  ### Quick Start: Convenience Functions (One-off Use)
105
140
 
106
141
  ```python
@@ -129,14 +164,29 @@ if result.is_valid:
129
164
 
130
165
  ### Production Use: Validator Class (Recommended)
131
166
 
132
- For production code with multiple validations, use the `Validator` class for better performance:
167
+ For production code with multiple validations, use the `Validator` class for better performance. Create validators via **factory methods** or from a metadata store:
133
168
 
134
169
  ```python
135
170
  from pycharter import Validator
136
171
 
137
- # Create validator from contract directory or file
138
- validator = Validator(contract_dir="data/contracts/user")
139
- # Or: validator = Validator(contract_file="user_contract.yaml")
172
+ # From directory (expects schema.yaml, coercion_rules.yaml, validation_rules.yaml)
173
+ validator = Validator.from_dir("data/contracts/user")
174
+
175
+ # From explicit files (any filenames)
176
+ validator = Validator.from_files(
177
+ schema="schemas/user.yaml",
178
+ coercion_rules="rules/coercion.yaml",
179
+ validation_rules="rules/validation.yaml"
180
+ )
181
+
182
+ # From a single contract file
183
+ validator = Validator.from_file("user_contract.yaml")
184
+
185
+ # From dictionaries
186
+ validator = Validator.from_dict(schema={...}, coercion_rules={...}, validation_rules={...})
187
+
188
+ # From metadata store (with database)
189
+ validator = Validator(store=store, schema_id="user_schema_v1")
140
190
 
141
191
  # Validate multiple records efficiently (model is cached)
142
192
  result1 = validator.validate({"name": "Alice", "age": 30})
@@ -169,11 +219,12 @@ PyCharter's API is organized into **three tiers** to help you choose the right a
169
219
  ### Tier 1: Primary Interfaces (⭐ Recommended for Production)
170
220
 
171
221
  **Classes** that provide the best performance and most features:
172
- - **`Validator`** - Primary validation interface (use for multiple validations)
222
+ - **`Validator`** - Primary validation interface (use for multiple validations); create via `from_dir()`, `from_files()`, `from_file()`, `from_dict()` or from store
223
+ - **`Pipeline`** - ETL pipeline (programmatic or config-driven); create via `from_config_files()`, `from_config_dir()`, `from_config_file()` or constructor
173
224
  - **`QualityCheck`** - Primary quality assurance interface
174
225
  - **`MetadataStoreClient`** - Base class for metadata stores
175
226
 
176
- **When to use**: Production code, batch processing, when you need to validate multiple records.
227
+ **When to use**: Production code, batch processing, when you need to validate multiple records or run ETL pipelines.
177
228
 
178
229
  ### Tier 2: Convenience Functions (Quick Start)
179
230
 
@@ -467,20 +518,24 @@ PyCharter provides validation through three tiers:
467
518
  ```python
468
519
  from pycharter import Validator, SQLiteMetadataStore
469
520
 
470
- # Option 1: From contract directory (no database)
471
- validator = Validator(contract_dir="data/contracts/user")
521
+ # Option 1: From directory (schema.yaml, coercion_rules.yaml, validation_rules.yaml)
522
+ validator = Validator.from_dir("data/contracts/user")
523
+ result = validator.validate({"name": "Alice", "age": 30})
524
+
525
+ # Option 2: From explicit files
526
+ validator = Validator.from_files(schema="schemas/user.yaml", coercion_rules="rules/coercion.yaml")
527
+ result = validator.validate({"name": "Alice", "age": 30})
528
+
529
+ # Option 3: From single contract file
530
+ validator = Validator.from_file("user_contract.yaml")
472
531
  result = validator.validate({"name": "Alice", "age": 30})
473
532
 
474
- # Option 2: From metadata store (with database)
533
+ # Option 4: From metadata store (with database)
475
534
  store = SQLiteMetadataStore("metadata.db")
476
535
  store.connect()
477
536
  validator = Validator(store=store, schema_id="user_schema_v1")
478
537
  result = validator.validate({"name": "Alice", "age": 30})
479
538
 
480
- # Option 3: From contract file
481
- validator = Validator(contract_file="user_contract.yaml")
482
- result = validator.validate({"name": "Alice", "age": 30})
483
-
484
539
  # Batch validation (efficient - model cached)
485
540
  results = validator.validate_batch([data1, data2, data3])
486
541
  ```
@@ -521,6 +576,55 @@ results = validate_batch(UserModel, [data1, data2, data3])
521
576
 
522
577
  ---
523
578
 
579
+ ### 5b. 🔄 ETL Pipelines (`pycharter.etl_generator`)
580
+
581
+ **Purpose**: Build and run ETL pipelines programmatically (with the `|` operator) or from YAML configs. No assumptions about project layout—you specify file paths or use a directory with standard filenames.
582
+
583
+ **When to Use**: When you need to extract, transform, and load data from config-driven or code-defined pipelines (HTTP, files, databases, cloud storage → transforms → Postgres, files, cloud).
584
+
585
+ **How It Works**:
586
+ - **Programmatic**: `Pipeline(extractor) | transformer | loader`; chain with `|`; call `await pipeline.run()`.
587
+ - **Config-driven**: Load from explicit files (`from_config_files`), from a directory with `extract.yaml`, `transform.yaml`, `load.yaml` (`from_config_dir`), or from a single `pipeline.yaml` (`from_config_file`).
588
+ - **Variables**: Pass `PipelineContext(variables={"API_KEY": "x"})` or `variables={...}` in factory methods; `${VAR}` and `${VAR:-default}` in configs are resolved from these (no built-in `CONTRACT_DIR`).
589
+ - **Async**: `run()` is async; use `asyncio.run(pipeline.run())` in scripts or `await pipeline.run()` in async code.
590
+ - **Error handling**: Optional `error_context` with `ErrorMode` (STRICT, LENIENT, COLLECT) controls whether extraction/load failures raise or are collected in `result.errors`.
591
+
592
+ **Example**:
593
+ ```python
594
+ import asyncio
595
+ from pycharter import Pipeline, PipelineContext, HTTPExtractor, PostgresLoader, Rename, AddField
596
+
597
+ # Programmatic
598
+ pipeline = (
599
+ Pipeline(HTTPExtractor(url="https://api.example.com/users"))
600
+ | Rename({"userName": "name"})
601
+ | AddField("processed_at", "now()")
602
+ | PostgresLoader(connection_string="...", table="users")
603
+ )
604
+ result = asyncio.run(pipeline.run())
605
+
606
+ # Config-driven (explicit files)
607
+ pipeline = Pipeline.from_config_files(
608
+ extract="configs/extract.yaml",
609
+ load="configs/load.yaml",
610
+ variables={"API_KEY": "secret"}
611
+ )
612
+
613
+ # Config-driven (directory: extract.yaml, transform.yaml, load.yaml)
614
+ pipeline = Pipeline.from_config_dir("pipelines/users/")
615
+
616
+ # Config-driven (single file)
617
+ pipeline = Pipeline.from_config_file("pipelines/users/pipeline.yaml")
618
+
619
+ result = asyncio.run(pipeline.run())
620
+ ```
621
+
622
+ **Exceptions**: Pipeline and config loading use PyCharter’s exception hierarchy: `PyCharterError` (base), `ConfigError`, `ConfigValidationError`, `ExpressionError`. See **Exceptions** under API Reference.
623
+
624
+ **See** `pycharter/etl_generator/ASYNC_AND_EXECUTION.md` for async usage and error modes.
625
+
626
+ ---
627
+
524
628
  ### 6. 🔍 Quality Assurance (`pycharter.quality`)
525
629
 
526
630
  **Purpose**: Data quality assurance pipeline that polices data according to data contracts, calculates quality metrics, tracks violations, and generates quality reports.
@@ -641,7 +745,7 @@ def process_user_data_quick(raw_data):
641
745
 
642
746
  ---
643
747
 
644
- ### 7. 🌐 REST API (`api/`)
748
+ ### 7. 🌐 REST API (`api/`) (`api/`)
645
749
 
646
750
  **Purpose**: Expose all PyCharter services as REST API endpoints.
647
751
 
@@ -689,6 +793,7 @@ See `api/README.md` for complete API documentation.
689
793
  | **Pydantic Generator** | JSON Schema | Pydantic models | Storage → Model Generation |
690
794
  | **JSON Schema Converter** | Pydantic models | JSON Schema | (Bidirectional) |
691
795
  | **Runtime Validator** | Pydantic models + Data | `ValidationResult` | Model Generation → Validation |
796
+ | **ETL Pipelines** | Config files or code | `PipelineResult` | Extract → Transform → Load |
692
797
  | **Quality Assurance** | Contract + Data | `QualityReport` | Validation → Quality Monitoring |
693
798
 
694
799
  Each service is designed to be **independent** yet **composable**, allowing you to use them individually or together as part of a complete data contract management system.
@@ -732,12 +837,9 @@ Product = from_file("product_schema.json", "Product")
732
837
  ```python
733
838
  from pycharter import Validator
734
839
 
735
- # From contract directory
736
- validator = Validator(contract_dir="data/contracts/article")
737
- result = validator.validate({"title": "My Article", "published": True})
738
-
739
- # From contract file
740
- validator = Validator(contract_file="article_contract.yaml")
840
+ # From directory or single file
841
+ validator = Validator.from_dir("data/contracts/article")
842
+ # or: validator = Validator.from_file("article_contract.yaml")
741
843
  result = validator.validate({"title": "My Article", "published": True})
742
844
  ```
743
845
 
@@ -956,11 +1058,12 @@ PyCharter's API is organized into three tiers to help you choose the right appro
956
1058
  ```python
957
1059
  from pycharter import Validator
958
1060
 
959
- # Create validator from various sources
960
- validator = Validator(contract_dir="data/contracts/user")
961
- validator = Validator(contract_file="contract.yaml")
962
- validator = Validator(store=store, schema_id="user_schema")
963
- validator = Validator(contract_dict={...})
1061
+ # Create validator via factory methods or store
1062
+ validator = Validator.from_dir("data/contracts/user")
1063
+ validator = Validator.from_files(schema="schema.yaml", coercion_rules="coercion.yaml")
1064
+ validator = Validator.from_file("contract.yaml")
1065
+ validator = Validator.from_dict(schema={...}, coercion_rules={...})
1066
+ validator = Validator(store=store, schema_id="user_schema") # from metadata store
964
1067
 
965
1068
  # Validate data
966
1069
  result = validator.validate(data)
@@ -1031,6 +1134,18 @@ store.connect()
1031
1134
  - **`MongoDBMetadataStore(connection_string: str)`** - MongoDB database
1032
1135
  - **`RedisMetadataStore(connection_string: str)`** - Redis database
1033
1136
 
1137
+ ### Exceptions
1138
+
1139
+ PyCharter uses a small exception hierarchy for config and pipeline errors. Catch **`PyCharterError`** to handle any PyCharter failure:
1140
+
1141
+ - **`PyCharterError`** - Base for all PyCharter exceptions
1142
+ - **`ConfigError`** - Config loading/parsing failures (missing file, invalid YAML)
1143
+ - **`ConfigValidationError`** - Schema validation failures (e.g. missing required `type` field)
1144
+ - **`ConfigLoadError`** - Config file load errors
1145
+ - **`ExpressionError`** - Expression evaluation failures (e.g. invalid syntax in AddField)
1146
+
1147
+ Pipeline **`run(error_context=...)`** supports **`ErrorMode`**: **STRICT** (raise on failure), **LENIENT** (log and continue), **COLLECT** (append to `result.errors`). Import from `pycharter.shared.errors`.
1148
+
1034
1149
  ## 🎯 Design Principles & Requirements
1035
1150
 
1036
1151
  Charter is designed to meet the following core requirements:
@@ -16,7 +16,18 @@ from fastapi.routing import APIRoute
16
16
  from pycharter import __version__ as pycharter_version
17
17
 
18
18
  # Import routers from v1
19
- from api.routes.v1 import contracts, metadata, quality, schemas, templates, validation, settings
19
+ from api.routes.v1 import (
20
+ contracts,
21
+ metadata,
22
+ quality,
23
+ schemas,
24
+ templates,
25
+ validation,
26
+ settings,
27
+ docs,
28
+ tracking,
29
+ evolution,
30
+ )
20
31
 
21
32
  # Try to import validation_jobs router (requires worker component)
22
33
  try:
@@ -128,6 +139,21 @@ def create_application() -> FastAPI:
128
139
  prefix=f"/api/{API_VERSION}",
129
140
  tags=["Settings"],
130
141
  )
142
+ app.include_router(
143
+ docs.router,
144
+ prefix=f"/api/{API_VERSION}",
145
+ tags=["Documentation"],
146
+ )
147
+ app.include_router(
148
+ tracking.router,
149
+ prefix=f"/api/{API_VERSION}",
150
+ tags=["Quality Tracking"],
151
+ )
152
+ app.include_router(
153
+ evolution.router,
154
+ prefix=f"/api/{API_VERSION}",
155
+ tags=["Schema Evolution"],
156
+ )
131
157
 
132
158
  # Include validation_jobs router if worker component is available
133
159
  if VALIDATION_JOBS_AVAILABLE:
@@ -0,0 +1,68 @@
1
+ """
2
+ API models for documentation generation endpoints.
3
+ """
4
+
5
+ from enum import Enum
6
+ from typing import Optional
7
+
8
+ from pydantic import BaseModel, Field
9
+
10
+
11
+ class DocsFormat(str, Enum):
12
+ """Supported documentation output formats."""
13
+
14
+ MARKDOWN = "markdown"
15
+ HTML = "html"
16
+
17
+
18
+ class DocsRequest(BaseModel):
19
+ """Request model for generating documentation from contract data."""
20
+
21
+ contract: dict = Field(..., description="Contract data to generate documentation for")
22
+ format: DocsFormat = Field(
23
+ default=DocsFormat.MARKDOWN, description="Output format for documentation"
24
+ )
25
+ include_schema: bool = Field(default=True, description="Include schema fields section")
26
+ include_coercions: bool = Field(
27
+ default=True, description="Include coercion rules section"
28
+ )
29
+ include_validations: bool = Field(
30
+ default=True, description="Include validation rules section"
31
+ )
32
+ include_metadata: bool = Field(
33
+ default=True, description="Include metadata/ownership section"
34
+ )
35
+
36
+
37
+ class DocsResponse(BaseModel):
38
+ """Response model for generated documentation."""
39
+
40
+ documentation: str = Field(..., description="Generated documentation content")
41
+ format: DocsFormat = Field(..., description="Format of the generated documentation")
42
+ schema_name: Optional[str] = Field(
43
+ default=None, description="Name of the schema documented"
44
+ )
45
+ version: Optional[str] = Field(
46
+ default=None, description="Version of the schema documented"
47
+ )
48
+
49
+
50
+ class DocsSectionRequest(BaseModel):
51
+ """Request model for generating a specific documentation section."""
52
+
53
+ contract: dict = Field(..., description="Contract data to generate documentation for")
54
+ section: str = Field(
55
+ ...,
56
+ description="Section to generate: 'schema', 'coercions', 'validations', 'metadata'",
57
+ )
58
+ format: DocsFormat = Field(
59
+ default=DocsFormat.MARKDOWN, description="Output format for documentation"
60
+ )
61
+
62
+
63
+ class DocsSectionResponse(BaseModel):
64
+ """Response model for a documentation section."""
65
+
66
+ section: str = Field(..., description="Name of the section generated")
67
+ content: str = Field(..., description="Generated section content")
68
+ format: DocsFormat = Field(..., description="Format of the generated content")