pycharter 0.0.20__py3-none-any.whl → 0.0.22__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 (222) hide show
  1. api/dependencies/__init__.py +2 -1
  2. api/dependencies/database.py +71 -5
  3. api/main.py +47 -8
  4. api/models/contracts.py +6 -4
  5. api/models/metadata.py +11 -7
  6. api/models/schemas.py +16 -10
  7. api/routes/v1/contracts.py +498 -226
  8. api/routes/v1/metadata.py +52 -211
  9. api/routes/v1/schemas.py +1 -1
  10. api/routes/v1/settings.py +88 -1
  11. api/utils.py +224 -0
  12. pycharter/__init__.py +149 -93
  13. pycharter/data/templates/template_transform_advanced.yaml +50 -0
  14. pycharter/data/templates/template_transform_simple.yaml +59 -0
  15. pycharter/db/models/base.py +1 -2
  16. pycharter/etl_generator/orchestrator.py +463 -487
  17. pycharter/metadata_store/postgres.py +16 -191
  18. pycharter/metadata_store/sqlite.py +12 -41
  19. {pycharter-0.0.20.dist-info → pycharter-0.0.22.dist-info}/METADATA +284 -62
  20. pycharter-0.0.22.dist-info/RECORD +358 -0
  21. ui/static/404/index.html +1 -1
  22. ui/static/404.html +1 -1
  23. ui/static/__next.__PAGE__.txt +1 -1
  24. ui/static/__next._full.txt +2 -2
  25. ui/static/__next._head.txt +1 -1
  26. ui/static/__next._index.txt +2 -2
  27. ui/static/__next._tree.txt +2 -2
  28. ui/static/_next/static/chunks/13d4a0fbd74c1ee4.js +1 -0
  29. ui/static/_next/static/chunks/2edb43b48432ac04.js +441 -0
  30. ui/static/_next/static/chunks/c4fa4f4114b7c352.js +1 -0
  31. ui/static/_next/static/chunks/d2363397e1b2bcab.css +1 -0
  32. ui/static/_next/static/chunks/f7d1a90dd75d2572.js +1 -0
  33. ui/static/_not-found/__next._full.txt +2 -2
  34. ui/static/_not-found/__next._head.txt +1 -1
  35. ui/static/_not-found/__next._index.txt +2 -2
  36. ui/static/_not-found/__next._not-found.__PAGE__.txt +1 -1
  37. ui/static/_not-found/__next._not-found.txt +1 -1
  38. ui/static/_not-found/__next._tree.txt +2 -2
  39. ui/static/_not-found/index.html +1 -1
  40. ui/static/_not-found/index.txt +2 -2
  41. ui/static/contracts/__next._full.txt +3 -3
  42. ui/static/contracts/__next._head.txt +1 -1
  43. ui/static/contracts/__next._index.txt +2 -2
  44. ui/static/contracts/__next._tree.txt +2 -2
  45. ui/static/contracts/__next.contracts.__PAGE__.txt +2 -2
  46. ui/static/contracts/__next.contracts.txt +1 -1
  47. ui/static/contracts/index.html +1 -1
  48. ui/static/contracts/index.txt +3 -3
  49. ui/static/documentation/__next._full.txt +3 -3
  50. ui/static/documentation/__next._head.txt +1 -1
  51. ui/static/documentation/__next._index.txt +2 -2
  52. ui/static/documentation/__next._tree.txt +2 -2
  53. ui/static/documentation/__next.documentation.__PAGE__.txt +2 -2
  54. ui/static/documentation/__next.documentation.txt +1 -1
  55. ui/static/documentation/index.html +2 -2
  56. ui/static/documentation/index.txt +3 -3
  57. ui/static/index.html +1 -1
  58. ui/static/index.txt +2 -2
  59. ui/static/metadata/__next._full.txt +2 -2
  60. ui/static/metadata/__next._head.txt +1 -1
  61. ui/static/metadata/__next._index.txt +2 -2
  62. ui/static/metadata/__next._tree.txt +2 -2
  63. ui/static/metadata/__next.metadata.__PAGE__.txt +1 -1
  64. ui/static/metadata/__next.metadata.txt +1 -1
  65. ui/static/metadata/index.html +1 -1
  66. ui/static/metadata/index.txt +2 -2
  67. ui/static/quality/__next._full.txt +2 -2
  68. ui/static/quality/__next._head.txt +1 -1
  69. ui/static/quality/__next._index.txt +2 -2
  70. ui/static/quality/__next._tree.txt +2 -2
  71. ui/static/quality/__next.quality.__PAGE__.txt +1 -1
  72. ui/static/quality/__next.quality.txt +1 -1
  73. ui/static/quality/index.html +2 -2
  74. ui/static/quality/index.txt +2 -2
  75. ui/static/rules/__next._full.txt +2 -2
  76. ui/static/rules/__next._head.txt +1 -1
  77. ui/static/rules/__next._index.txt +2 -2
  78. ui/static/rules/__next._tree.txt +2 -2
  79. ui/static/rules/__next.rules.__PAGE__.txt +1 -1
  80. ui/static/rules/__next.rules.txt +1 -1
  81. ui/static/rules/index.html +1 -1
  82. ui/static/rules/index.txt +2 -2
  83. ui/static/schemas/__next._full.txt +2 -2
  84. ui/static/schemas/__next._head.txt +1 -1
  85. ui/static/schemas/__next._index.txt +2 -2
  86. ui/static/schemas/__next._tree.txt +2 -2
  87. ui/static/schemas/__next.schemas.__PAGE__.txt +1 -1
  88. ui/static/schemas/__next.schemas.txt +1 -1
  89. ui/static/schemas/index.html +1 -1
  90. ui/static/schemas/index.txt +2 -2
  91. ui/static/settings/__next._full.txt +2 -2
  92. ui/static/settings/__next._head.txt +1 -1
  93. ui/static/settings/__next._index.txt +2 -2
  94. ui/static/settings/__next._tree.txt +2 -2
  95. ui/static/settings/__next.settings.__PAGE__.txt +1 -1
  96. ui/static/settings/__next.settings.txt +1 -1
  97. ui/static/settings/index.html +1 -1
  98. ui/static/settings/index.txt +2 -2
  99. ui/static/static/.gitkeep +0 -0
  100. ui/static/static/404/index.html +1 -0
  101. ui/static/static/404.html +1 -0
  102. ui/static/static/__next.__PAGE__.txt +10 -0
  103. ui/static/static/__next._full.txt +30 -0
  104. ui/static/static/__next._head.txt +7 -0
  105. ui/static/static/__next._index.txt +9 -0
  106. ui/static/static/__next._tree.txt +2 -0
  107. ui/static/static/_next/static/chunks/222442f6da32302a.js +1 -0
  108. ui/static/static/_next/static/chunks/247eb132b7f7b574.js +1 -0
  109. ui/static/static/_next/static/chunks/297d55555b71baba.js +1 -0
  110. ui/static/static/_next/static/chunks/2ab439ce003cd691.js +1 -0
  111. ui/static/static/_next/static/chunks/414e77373f8ff61c.js +1 -0
  112. ui/static/static/_next/static/chunks/49ca65abd26ae49e.js +1 -0
  113. ui/static/static/_next/static/chunks/5e04d10c4a7b58a3.js +1 -0
  114. ui/static/static/_next/static/chunks/652ad0aa26265c47.js +2 -0
  115. ui/static/static/_next/static/chunks/75d88a058d8ffaa6.js +1 -0
  116. ui/static/static/_next/static/chunks/8c89634cf6bad76f.js +1 -0
  117. ui/static/static/_next/static/chunks/9667e7a3d359eb39.js +1 -0
  118. ui/static/static/_next/static/chunks/9c23f44fff36548a.js +1 -0
  119. ui/static/static/_next/static/chunks/a6dad97d9634a72d.js +1 -0
  120. ui/static/static/_next/static/chunks/b32a0963684b9933.js +4 -0
  121. ui/static/static/_next/static/chunks/c69f6cba366bd988.js +1 -0
  122. ui/static/static/_next/static/chunks/db913959c675cea6.js +1 -0
  123. ui/static/static/_next/static/chunks/f061a4be97bfc3b3.js +1 -0
  124. ui/static/static/_next/static/chunks/f2e7afeab1178138.js +1 -0
  125. ui/static/static/_next/static/chunks/ff1a16fafef87110.js +1 -0
  126. ui/static/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +3 -0
  127. ui/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_buildManifest.js +11 -0
  128. ui/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_ssgManifest.js +1 -0
  129. ui/static/static/_not-found/__next._full.txt +17 -0
  130. ui/static/static/_not-found/__next._head.txt +7 -0
  131. ui/static/static/_not-found/__next._index.txt +9 -0
  132. ui/static/static/_not-found/__next._not-found.__PAGE__.txt +5 -0
  133. ui/static/static/_not-found/__next._not-found.txt +4 -0
  134. ui/static/static/_not-found/__next._tree.txt +2 -0
  135. ui/static/static/_not-found/index.html +1 -0
  136. ui/static/static/_not-found/index.txt +17 -0
  137. ui/static/static/contracts/__next._full.txt +21 -0
  138. ui/static/static/contracts/__next._head.txt +7 -0
  139. ui/static/static/contracts/__next._index.txt +9 -0
  140. ui/static/static/contracts/__next._tree.txt +2 -0
  141. ui/static/static/contracts/__next.contracts.__PAGE__.txt +9 -0
  142. ui/static/static/contracts/__next.contracts.txt +4 -0
  143. ui/static/static/contracts/index.html +1 -0
  144. ui/static/static/contracts/index.txt +21 -0
  145. ui/static/static/documentation/__next._full.txt +21 -0
  146. ui/static/static/documentation/__next._head.txt +7 -0
  147. ui/static/static/documentation/__next._index.txt +9 -0
  148. ui/static/static/documentation/__next._tree.txt +2 -0
  149. ui/static/static/documentation/__next.documentation.__PAGE__.txt +9 -0
  150. ui/static/static/documentation/__next.documentation.txt +4 -0
  151. ui/static/static/documentation/index.html +93 -0
  152. ui/static/static/documentation/index.txt +21 -0
  153. ui/static/static/index.html +1 -0
  154. ui/static/static/index.txt +30 -0
  155. ui/static/static/metadata/__next._full.txt +21 -0
  156. ui/static/static/metadata/__next._head.txt +7 -0
  157. ui/static/static/metadata/__next._index.txt +9 -0
  158. ui/static/static/metadata/__next._tree.txt +2 -0
  159. ui/static/static/metadata/__next.metadata.__PAGE__.txt +9 -0
  160. ui/static/static/metadata/__next.metadata.txt +4 -0
  161. ui/static/static/metadata/index.html +1 -0
  162. ui/static/static/metadata/index.txt +21 -0
  163. ui/static/static/quality/__next._full.txt +21 -0
  164. ui/static/static/quality/__next._head.txt +7 -0
  165. ui/static/static/quality/__next._index.txt +9 -0
  166. ui/static/static/quality/__next._tree.txt +2 -0
  167. ui/static/static/quality/__next.quality.__PAGE__.txt +9 -0
  168. ui/static/static/quality/__next.quality.txt +4 -0
  169. ui/static/static/quality/index.html +2 -0
  170. ui/static/static/quality/index.txt +21 -0
  171. ui/static/static/rules/__next._full.txt +21 -0
  172. ui/static/static/rules/__next._head.txt +7 -0
  173. ui/static/static/rules/__next._index.txt +9 -0
  174. ui/static/static/rules/__next._tree.txt +2 -0
  175. ui/static/static/rules/__next.rules.__PAGE__.txt +9 -0
  176. ui/static/static/rules/__next.rules.txt +4 -0
  177. ui/static/static/rules/index.html +1 -0
  178. ui/static/static/rules/index.txt +21 -0
  179. ui/static/static/schemas/__next._full.txt +21 -0
  180. ui/static/static/schemas/__next._head.txt +7 -0
  181. ui/static/static/schemas/__next._index.txt +9 -0
  182. ui/static/static/schemas/__next._tree.txt +2 -0
  183. ui/static/static/schemas/__next.schemas.__PAGE__.txt +9 -0
  184. ui/static/static/schemas/__next.schemas.txt +4 -0
  185. ui/static/static/schemas/index.html +1 -0
  186. ui/static/static/schemas/index.txt +21 -0
  187. ui/static/static/settings/__next._full.txt +21 -0
  188. ui/static/static/settings/__next._head.txt +7 -0
  189. ui/static/static/settings/__next._index.txt +9 -0
  190. ui/static/static/settings/__next._tree.txt +2 -0
  191. ui/static/static/settings/__next.settings.__PAGE__.txt +9 -0
  192. ui/static/static/settings/__next.settings.txt +4 -0
  193. ui/static/static/settings/index.html +1 -0
  194. ui/static/static/settings/index.txt +21 -0
  195. ui/static/static/validation/__next._full.txt +21 -0
  196. ui/static/static/validation/__next._head.txt +7 -0
  197. ui/static/static/validation/__next._index.txt +9 -0
  198. ui/static/static/validation/__next._tree.txt +2 -0
  199. ui/static/static/validation/__next.validation.__PAGE__.txt +9 -0
  200. ui/static/static/validation/__next.validation.txt +4 -0
  201. ui/static/static/validation/index.html +1 -0
  202. ui/static/static/validation/index.txt +21 -0
  203. ui/static/validation/__next._full.txt +2 -2
  204. ui/static/validation/__next._head.txt +1 -1
  205. ui/static/validation/__next._index.txt +2 -2
  206. ui/static/validation/__next._tree.txt +2 -2
  207. ui/static/validation/__next.validation.__PAGE__.txt +1 -1
  208. ui/static/validation/__next.validation.txt +1 -1
  209. ui/static/validation/index.html +1 -1
  210. ui/static/validation/index.txt +2 -2
  211. pycharter/db/schemas/.ipynb_checkpoints/data_contract-checkpoint.py +0 -160
  212. pycharter-0.0.20.dist-info/RECORD +0 -247
  213. {pycharter-0.0.20.dist-info → pycharter-0.0.22.dist-info}/WHEEL +0 -0
  214. {pycharter-0.0.20.dist-info → pycharter-0.0.22.dist-info}/entry_points.txt +0 -0
  215. {pycharter-0.0.20.dist-info → pycharter-0.0.22.dist-info}/licenses/LICENSE +0 -0
  216. {pycharter-0.0.20.dist-info → pycharter-0.0.22.dist-info}/top_level.txt +0 -0
  217. /ui/static/_next/static/{tNTkVW6puVXC4bAm4WrHl → 0rYA78L88aUyD2Uh38hhX}/_buildManifest.js +0 -0
  218. /ui/static/_next/static/{tNTkVW6puVXC4bAm4WrHl → 0rYA78L88aUyD2Uh38hhX}/_ssgManifest.js +0 -0
  219. /ui/static/{_next → static/_next}/static/chunks/4e310fe5005770a3.css +0 -0
  220. /ui/static/{_next → static/_next}/static/chunks/5fc14c00a2779dc5.js +0 -0
  221. /ui/static/{_next → static/_next}/static/chunks/b584574fdc8ab13e.js +0 -0
  222. /ui/static/{_next → static/_next}/static/chunks/d5989c94d3614b3a.js +0 -0
@@ -0,0 +1,441 @@
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,33558,e=>{"use strict";var t=e.i(43476),a=e.i(71645),i=e.i(19455),r=e.i(61246),o=e.i(75254);let s=(0,o.default)("Play",[["polygon",{points:"6 3 20 12 6 21 6 3",key:"1oa8hb"}]]),n=(0,o.default)("Copy",[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]]),l=(0,o.default)("Check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]]);var d=e.i(78583),c=e.i(58041);let m=(0,o.default)("Code",[["polyline",{points:"16 18 22 12 16 6",key:"z7tu5w"}],["polyline",{points:"8 6 2 12 8 18",key:"1eg1df"}]]),p=(0,o.default)("ShieldCheck",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);var u=e.i(42009);e.i(80428);var h=e.i(50398);let _=[{id:"parse_contract",title:"Contract Parser",description:"Read and decompose data contract files",method:"parse_contract(contract_dict, validate=True)",apiEndpoint:"/api/v1/contracts/parse",apiMethod:"POST",exampleRequest:{contract:{schema:{type:"object",properties:{name:{type:"string"},age:{type:"integer"}}},metadata:{title:"User Contract",version:"1.0.0"}}},exampleCode:`from pycharter import parse_contract, parse_contract_file
2
+
3
+ parse_contract(contract_dict)
4
+ parse_contract_file(file_path)`,arguments:[{name:"contract_data",type:"Dict[str, Any]",description:"Contract data as dictionary containing schema, metadata, ownership, governance_rules, coercion_rules, and validation_rules",required:!0},{name:"validate",type:"bool",description:"If True (default), validate contract against schema before parsing",required:!1,default:"True"}],returns:{type:"ContractMetadata",description:"ContractMetadata object with decomposed components (schema, metadata, ownership, governance_rules, coercion_rules, validation_rules) and version tracking"}},{id:"parse_contract_file",title:"Contract Parser - From File",description:"Parse a data contract from an uploaded file (YAML or JSON)",method:"parse_contract_file(file_path, validate=True)",apiEndpoint:"/api/v1/contracts/parse/upload",apiMethod:"POST",exampleRequest:null,exampleCode:`from pycharter import parse_contract_file
5
+
6
+ # Parse contract from file
7
+ contract_metadata = parse_contract_file("contract.yaml")
8
+ # or
9
+ contract_metadata = parse_contract_file("contract.json", validate=True)`,arguments:[{name:"file_path",type:"str",description:"Path to contract file (YAML or JSON)",required:!0},{name:"validate",type:"bool",description:"If True (default), validate contract against schema before parsing",required:!1,default:"True"}],returns:{type:"ContractMetadata",description:"ContractMetadata object with decomposed components (schema, metadata, ownership, governance_rules, coercion_rules, validation_rules)"}},{id:"build_contract",title:"Contract Builder",description:"Construct consolidated contracts from separate artifacts",method:"build_contract(artifacts: ContractArtifacts, include_metadata=True, include_ownership=True, include_governance=True)",apiEndpoint:"/api/v1/contracts/build",apiMethod:"POST",exampleRequest:{artifacts:{schema:{type:"object",version:"1.0.0",properties:{name:{type:"string"},age:{type:"integer"}}},coercion_rules:{version:"1.0.0",age:"coerce_to_integer"},validation_rules:{version:"1.0.0",age:{greater_than_or_equal_to:{threshold:0}}},metadata:{version:"1.0.0",description:"User contract"}},include_metadata:!0,include_ownership:!0,include_governance:!0},exampleCode:`from pycharter import build_contract, ContractArtifacts
10
+
11
+ artifacts = ContractArtifacts(
12
+ schema={"type": "object", "version": "1.0.0", "properties": {...}},
13
+ coercion_rules={"version": "1.0.0", "age": "coerce_to_integer"},
14
+ validation_rules={"version": "1.0.0", "age": {...}},
15
+ metadata={"version": "1.0.0", "description": "User contract"}
16
+ )
17
+ contract = build_contract(artifacts)`,arguments:[{name:"artifacts",type:"ContractArtifacts",description:"ContractArtifacts dataclass containing schema (required), coercion_rules (optional), validation_rules (optional), and metadata (optional)",required:!0},{name:"include_metadata",type:"bool",description:"Whether to include metadata in the contract",required:!1,default:"True"},{name:"include_ownership",type:"bool",description:"Whether to include ownership information",required:!1,default:"True"},{name:"include_governance",type:"bool",description:"Whether to include governance rules",required:!1,default:"True"}],returns:{type:"Dict[str, Any]",description:"Consolidated contract dictionary ready for runtime validation, containing schema (with merged coercion/validation rules), coercion_rules, validation_rules, metadata (if included), and versions tracking dictionary"}},{id:"build_contract_from_store",title:"Contract Builder - From Store",description:"Build a consolidated contract from artifacts stored in metadata store with individual version control for each component",method:"build_contract_from_store(store, schema_title, schema_version=None, coercion_rules_title=None, coercion_rules_version=None, validation_rules_title=None, validation_rules_version=None, metadata_title=None, metadata_version=None)",apiEndpoint:"/api/v1/contracts/build",apiMethod:"POST",exampleRequest:{schema_title:"user_schema",schema_version:"1.0.0",coercion_rules_title:"user_schema",coercion_rules_version:"1.0.0",validation_rules_title:"user_schema",validation_rules_version:"1.0.0",metadata_title:"user_schema",metadata_version:"1.0.0"},exampleCode:`from pycharter import build_contract_from_store
18
+
19
+ store = PostgresMetadataStore(connection_string)
20
+ store.connect()
21
+ contract = build_contract_from_store(
22
+ store=store,
23
+ schema_title="user_schema",
24
+ schema_version="1.0.0",
25
+ coercion_rules_title="user_schema",
26
+ coercion_rules_version="1.0.0",
27
+ validation_rules_title="user_schema",
28
+ validation_rules_version="1.0.0",
29
+ metadata_title="user_schema",
30
+ metadata_version="1.0.0"
31
+ )`,arguments:[{name:"store",type:"MetadataStoreClient",description:"MetadataStoreClient instance connected to the metadata store",required:!0},{name:"schema_title",type:"str",description:"Schema title/identifier",required:!0},{name:"schema_version",type:"Optional[str]",description:"Optional schema version (if None, uses latest version)",required:!1,default:"None"},{name:"coercion_rules_title",type:"Optional[str]",description:"Optional coercion rules title/identifier (if None, uses schema_title)",required:!1,default:"None"},{name:"coercion_rules_version",type:"Optional[str]",description:"Optional coercion rules version (if None, uses latest version or schema_version)",required:!1,default:"None"},{name:"validation_rules_title",type:"Optional[str]",description:"Optional validation rules title/identifier (if None, uses schema_title)",required:!1,default:"None"},{name:"validation_rules_version",type:"Optional[str]",description:"Optional validation rules version (if None, uses latest version or schema_version)",required:!1,default:"None"},{name:"metadata_title",type:"Optional[str]",description:"Optional metadata title/identifier (if None, uses schema_title)",required:!1,default:"None"},{name:"metadata_version",type:"Optional[str]",description:"Optional metadata version (if None, uses latest version or schema_version)",required:!1,default:"None"}],returns:{type:"Dict[str, Any]",description:"Consolidated contract dictionary ready for runtime validation, containing schema (with merged coercion/validation rules), coercion_rules, validation_rules, metadata (if included), and versions tracking dictionary"}},{id:"store_schema",title:"Metadata Store - Store Schema",description:"Store a JSON Schema in the metadata store",method:"store.store_schema(schema_name, schema, version)",apiEndpoint:"/api/v1/metadata/schemas",apiMethod:"POST",exampleRequest:{schema_name:"user_schema",schema:{type:"object",properties:{name:{type:"string"},age:{type:"integer"}}},version:"1.0.0"},exampleCode:`from pycharter import MetadataStoreClient
32
+
33
+ store = MetadataStoreClient(database_url)
34
+ store.store_schema(schema_id, schema, version)
35
+ store.get_schema(schema_id, version)
36
+ store.store_metadata(schema_id, metadata, version)`,arguments:[{name:"schema_name",type:"str",description:"Name/identifier for the schema (used as data_contract name)",required:!0},{name:"schema",type:"Dict[str, Any]",description:'JSON Schema dictionary (must contain "version" field or it will be added)',required:!0},{name:"version",type:"str",description:'Required version string (must match schema["version"] if present)',required:!0}],returns:{type:"str",description:"Schema ID or identifier"}},{id:"get_schema",title:"Metadata Store - Get Schema",description:"Retrieve a schema from the metadata store",method:"store.get_schema(schema_id, version=None)",apiEndpoint:"/api/v1/metadata/schemas/{schema_id}",apiMethod:"GET",exampleRequest:null,exampleCode:`from pycharter import MetadataStoreClient
37
+
38
+ store = MetadataStoreClient(database_url)
39
+ store.get_schema(schema_id, version)`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, returns latest version)",required:!1,default:"None"}],returns:{type:"Optional[Dict[str, Any]]",description:"Schema dictionary with version included, or None if not found"}},{id:"list_schemas",title:"Metadata Store - List Schemas",description:"Retrieve a list of all schemas stored in the metadata store",method:"store.list_schemas()",apiEndpoint:"/api/v1/metadata/schemas",apiMethod:"GET",exampleRequest:null,exampleCode:`from pycharter import PostgresMetadataStore
40
+
41
+ store = PostgresMetadataStore(connection_string)
42
+ store.connect()
43
+
44
+ # List all schemas
45
+ schemas = store.list_schemas()
46
+ for schema in schemas:
47
+ print(f"Schema: {schema.get('name')}, Version: {schema.get('version')}")`,arguments:[],returns:{type:"List[Dict[str, Any]]",description:"List of schema metadata dictionaries, each containing id, name, title, and version"}},{id:"store_metadata",title:"Metadata Store - Store Metadata",description:"Store metadata (ownership, governance rules, etc.) for a schema",method:"store.store_metadata(schema_id, metadata, version=None)",apiEndpoint:"/api/v1/metadata/metadata",apiMethod:"POST",exampleRequest:{schema_id:"user_schema",metadata:{title:"user_schema_metadata",description:"Metadata for user schema",business_owners:["owner@example.com"],team:"data-engineering",governance_rules:{data_retention:{days:2555},access_control:{level:"public"}}},version:"1.0.0"},exampleCode:`from pycharter import PostgresMetadataStore
48
+
49
+ store = PostgresMetadataStore(connection_string)
50
+ store.connect()
51
+
52
+ # Store metadata for a schema
53
+ metadata_id = store.store_metadata(
54
+ schema_id='user_schema',
55
+ metadata={
56
+ 'title': 'user_schema_metadata',
57
+ 'description': 'Metadata for user schema',
58
+ 'business_owners': ['owner@example.com'],
59
+ 'team': 'data-engineering',
60
+ 'governance_rules': {
61
+ 'data_retention': {'days': 2555},
62
+ 'access_control': {'level': 'public'}
63
+ }
64
+ },
65
+ version='1.0.0'
66
+ )`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"metadata",type:"Dict[str, Any]",description:"Metadata dictionary containing ownership, governance_rules, and other metadata",required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, uses schema version)",required:!1,default:"None"}],returns:{type:"str",description:"Metadata record ID"}},{id:"get_metadata",title:"Metadata Store - Get Metadata",description:"Retrieve metadata for a schema from the metadata store",method:"store.get_metadata(schema_id, version=None)",apiEndpoint:"/api/v1/metadata/metadata/{schema_id}",apiMethod:"GET",exampleRequest:null,exampleCode:`from pycharter import PostgresMetadataStore
67
+
68
+ store = PostgresMetadataStore(connection_string)
69
+ store.connect()
70
+
71
+ # Get metadata for a schema
72
+ metadata = store.get_metadata(
73
+ schema_id='user_schema',
74
+ version='1.0.0' # Optional, defaults to latest
75
+ )`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, uses latest version)",required:!1,default:"None"}],returns:{type:"Optional[Dict[str, Any]]",description:"Metadata dictionary or None if not found"}},{id:"get_complete_schema",title:"Metadata Store - Get Complete Schema",description:"Retrieve a complete schema with coercion and validation rules merged",method:"store.get_complete_schema(schema_id, version=None)",apiEndpoint:"/api/v1/metadata/schemas/{schema_id}/complete",apiMethod:"GET",exampleRequest:null,exampleCode:`from pycharter import PostgresMetadataStore
76
+
77
+ store = PostgresMetadataStore(connection_string)
78
+ store.connect()
79
+
80
+ # Get complete schema with rules merged
81
+ complete_schema = store.get_complete_schema(
82
+ schema_id='user_schema',
83
+ version='1.0.0' # Optional, defaults to latest
84
+ )
85
+ # The schema now includes coercion and validation rules
86
+ # merged into the properties`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, defaults to latest)",required:!1,default:"None"}],returns:{type:"Optional[Dict[str, Any]]",description:"Complete schema dictionary with coercion and validation rules merged into the properties, or None if not found"}},{id:"store_coercion_rules",title:"Metadata Store - Store Coercion Rules",description:"Store coercion rules that define how data should be transformed before validation",method:"store.store_coercion_rules(schema_id, coercion_rules, version=None)",apiEndpoint:"/api/v1/metadata/coercion-rules",apiMethod:"POST",exampleRequest:{schema_id:"user_schema",coercion_rules:{age:"coerce_to_integer",email:"coerce_to_lowercase",price:"coerce_to_float",name:"coerce_to_stripped_string"},version:"1.0.0"},exampleCode:`from pycharter import PostgresMetadataStore
87
+
88
+ store = PostgresMetadataStore(connection_string)
89
+ store.connect()
90
+
91
+ # Store coercion rules for a schema
92
+ rule_id = store.store_coercion_rules(
93
+ schema_id='user_schema',
94
+ coercion_rules={
95
+ 'age': 'coerce_to_integer',
96
+ 'email': 'coerce_to_lowercase',
97
+ 'name': 'coerce_to_stripped_string'
98
+ },
99
+ version='1.0.0'
100
+ )`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"coercion_rules",type:"Dict[str, Any]",description:'Dictionary mapping field names to coercion rule types (e.g., "coerce_to_integer", "coerce_to_lowercase")',required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, uses schema version)",required:!1,default:"None"}],returns:{type:"str",description:"Coercion rule record ID"}},{id:"get_coercion_rules",title:"Metadata Store - Get Coercion Rules",description:"Retrieve coercion rules for a schema from the metadata store",method:"store.get_coercion_rules(schema_id, version=None)",apiEndpoint:"/api/v1/metadata/coercion-rules/{schema_id}",apiMethod:"GET",exampleRequest:null,exampleCode:`from pycharter import PostgresMetadataStore
101
+
102
+ store = PostgresMetadataStore(connection_string)
103
+ store.connect()
104
+
105
+ # Get coercion rules for a schema
106
+ coercion_rules = store.get_coercion_rules(
107
+ schema_id='user_schema',
108
+ version='1.0.0' # Optional, defaults to latest
109
+ )`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, defaults to latest)",required:!1,default:"None"}],returns:{type:"Optional[Dict[str, Any]]",description:"Coercion rules dictionary mapping field names to coercion types, or None if not found"}},{id:"store_validation_rules",title:"Metadata Store - Store Validation Rules",description:"Store validation rules that define custom validation logic beyond JSON Schema",method:"store.store_validation_rules(schema_id, validation_rules, version=None)",apiEndpoint:"/api/v1/metadata/validation-rules",apiMethod:"POST",exampleRequest:{schema_id:"user_schema",validation_rules:{age:{greater_than_or_equal_to:{threshold:0},less_than_or_equal_to:{threshold:150}},email:{min_length:{threshold:5},matches_pattern:{pattern:"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"}}},version:"1.0.0"},exampleCode:`from pycharter import PostgresMetadataStore
110
+
111
+ store = PostgresMetadataStore(connection_string)
112
+ store.connect()
113
+
114
+ # Store validation rules for a schema
115
+ rule_id = store.store_validation_rules(
116
+ schema_id='user_schema',
117
+ validation_rules={
118
+ 'age': {
119
+ 'greater_than_or_equal_to': {'threshold': 0},
120
+ 'less_than_or_equal_to': {'threshold': 150}
121
+ },
122
+ 'email': {
123
+ 'min_length': {'threshold': 5},
124
+ 'matches_pattern': {'pattern': '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'}
125
+ }
126
+ },
127
+ version='1.0.0'
128
+ )`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"validation_rules",type:"Dict[str, Any]",description:'Dictionary mapping field names to validation rule dictionaries (e.g., {"age": {"greater_than_or_equal_to": {"threshold": 0}}})',required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, uses schema version)",required:!1,default:"None"}],returns:{type:"str",description:"Validation rule record ID"}},{id:"get_validation_rules",title:"Metadata Store - Get Validation Rules",description:"Retrieve validation rules for a schema from the metadata store",method:"store.get_validation_rules(schema_id, version=None)",apiEndpoint:"/api/v1/metadata/validation-rules/{schema_id}",apiMethod:"GET",exampleRequest:null,exampleCode:`from pycharter import PostgresMetadataStore
129
+
130
+ store = PostgresMetadataStore(connection_string)
131
+ store.connect()
132
+
133
+ # Get validation rules for a schema
134
+ validation_rules = store.get_validation_rules(
135
+ schema_id='user_schema',
136
+ version='1.0.0' # Optional, defaults to latest
137
+ )`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, defaults to latest)",required:!1,default:"None"}],returns:{type:"Optional[Dict[str, Any]]",description:"Validation rules dictionary mapping field names to validation rule dictionaries, or None if not found"}},{id:"generate_model",title:"Pydantic Generator",description:"Generate Pydantic models from JSON Schema",method:'generate_model(schema, model_name="DynamicModel")',apiEndpoint:"/api/v1/schemas/generate",apiMethod:"POST",exampleRequest:{schema:{type:"object",properties:{name:{type:"string"},age:{type:"integer"}}},model_name:"User"},exampleCode:`from pycharter import generate_model, generate_model_file, from_dict, from_file, from_json, from_url
138
+
139
+ # Advanced: More control
140
+ UserModel = generate_model(schema_dict, model_name="User")
141
+
142
+ # Quick helpers: Generate and return model
143
+ UserModel = from_dict(schema_dict) # From dictionary
144
+ UserModel = from_file("schema.json") # From file
145
+ UserModel = from_json(json_string) # From JSON string
146
+ UserModel = from_url("https://example.com/schema.json") # From URL
147
+
148
+ # Generate model and save to file
149
+ generate_model_file(schema_dict, "models.py", model_name="User")`,arguments:[{name:"schema",type:"Dict[str, Any]",description:"JSON Schema dictionary",required:!0},{name:"model_name",type:"str",description:"Name for the generated Pydantic model class",required:!1,default:'"DynamicModel"'}],returns:{type:"Type[BaseModel]",description:"A Pydantic model class generated from the schema"}},{id:"from_dict",title:"Generate Model from Dict",description:"Quick helper: Generate Pydantic model from JSON Schema dictionary",method:"from_dict(schema_dict)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import from_dict
150
+
151
+ schema = {
152
+ "type": "object",
153
+ "properties": {
154
+ "name": {"type": "string"},
155
+ "age": {"type": "integer"}
156
+ }
157
+ }
158
+
159
+ UserModel = from_dict(schema)
160
+ user = UserModel(name="Alice", age=30)`,arguments:[{name:"schema_dict",type:"Dict[str, Any]",description:"JSON Schema dictionary",required:!0}],returns:{type:"Type[BaseModel]",description:"Pydantic model class generated from the schema"}},{id:"from_file",title:"Generate Model from File",description:"Quick helper: Generate Pydantic model from JSON Schema file",method:"from_file(file_path)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import from_file
161
+
162
+ UserModel = from_file("schema.json")
163
+ # or
164
+ UserModel = from_file("schema.yaml")`,arguments:[{name:"file_path",type:"str",description:"Path to JSON Schema file (JSON or YAML)",required:!0}],returns:{type:"Type[BaseModel]",description:"Pydantic model class generated from the schema file"}},{id:"from_json",title:"Generate Model from JSON String",description:"Quick helper: Generate Pydantic model from JSON Schema JSON string",method:"from_json(json_string)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import from_json
165
+
166
+ json_schema = '{"type": "object", "properties": {"name": {"type": "string"}}}'
167
+ UserModel = from_json(json_schema)`,arguments:[{name:"json_string",type:"str",description:"JSON Schema as JSON string",required:!0}],returns:{type:"Type[BaseModel]",description:"Pydantic model class generated from the JSON string"}},{id:"from_url",title:"Generate Model from URL",description:"Quick helper: Generate Pydantic model from JSON Schema URL",method:"from_url(url)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import from_url
168
+
169
+ UserModel = from_url("https://example.com/schema.json")`,arguments:[{name:"url",type:"str",description:"URL to JSON Schema file",required:!0}],returns:{type:"Type[BaseModel]",description:"Pydantic model class generated from the URL"}},{id:"generate_model_file",title:"Generate Model File",description:"Generate Pydantic model and save to Python file",method:'generate_model_file(schema, output_file, model_name="DynamicModel")',apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import generate_model_file
170
+
171
+ schema = {
172
+ "type": "object",
173
+ "properties": {
174
+ "name": {"type": "string"},
175
+ "age": {"type": "integer"}
176
+ }
177
+ }
178
+
179
+ generate_model_file(
180
+ schema=schema,
181
+ output_file="models.py",
182
+ model_name="User"
183
+ )`,arguments:[{name:"schema",type:"Dict[str, Any]",description:"JSON Schema dictionary",required:!0},{name:"output_file",type:"str",description:"Path to output Python file",required:!0},{name:"model_name",type:"str",description:"Name for the generated Pydantic model class",required:!1,default:'"DynamicModel"'}],returns:{type:"None",description:"Saves the generated model to the specified file"}},{id:"model_to_schema",title:"JSON Schema Converter (Advanced)",description:"Convert Pydantic models to JSON Schema - core conversion function",method:"model_to_schema(model_class)",apiEndpoint:"/api/v1/schemas/convert",apiMethod:"POST",exampleRequest:{model_class:"pydantic.BaseModel"},exampleCode:`from pycharter import model_to_schema
184
+ from pydantic import BaseModel
185
+
186
+ class UserModel(BaseModel):
187
+ name: str
188
+ age: int
189
+
190
+ schema = model_to_schema(UserModel)
191
+ print(schema)`,arguments:[{name:"model_class",type:"Type[BaseModel] | str",description:'Pydantic model class or fully qualified class name (e.g., "mymodule.UserModel")',required:!0}],returns:{type:"Dict[str, Any]",description:"JSON Schema dictionary with optional title and version fields"}},{id:"to_dict",title:"Convert Model to Dict",description:"Quick helper: Convert Pydantic model to JSON Schema dictionary",method:"to_dict(model_class)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import to_dict
192
+ from pydantic import BaseModel
193
+
194
+ class UserModel(BaseModel):
195
+ name: str
196
+ age: int
197
+
198
+ schema = to_dict(UserModel)`,arguments:[{name:"model_class",type:"Type[BaseModel] | str",description:"Pydantic model class or fully qualified class name",required:!0}],returns:{type:"Dict[str, Any]",description:"JSON Schema dictionary"}},{id:"to_json",title:"Convert Model to JSON String",description:"Quick helper: Convert Pydantic model to JSON Schema JSON string",method:"to_json(model_class)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import to_json
199
+ from pydantic import BaseModel
200
+
201
+ class UserModel(BaseModel):
202
+ name: str
203
+ age: int
204
+
205
+ json_schema = to_json(UserModel)
206
+ print(json_schema)`,arguments:[{name:"model_class",type:"Type[BaseModel] | str",description:"Pydantic model class or fully qualified class name",required:!0}],returns:{type:"str",description:"JSON Schema as JSON string"}},{id:"to_file",title:"Convert Model to File",description:"Quick helper: Convert Pydantic model to JSON Schema file",method:"to_file(model_class, file_path)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import to_file
207
+ from pydantic import BaseModel
208
+
209
+ class UserModel(BaseModel):
210
+ name: str
211
+ age: int
212
+
213
+ to_file(UserModel, "schema.json")
214
+ # or
215
+ to_file(UserModel, "schema.yaml")`,arguments:[{name:"model_class",type:"Type[BaseModel] | str",description:"Pydantic model class or fully qualified class name",required:!0},{name:"file_path",type:"str",description:"Path to output file (JSON or YAML)",required:!0}],returns:{type:"None",description:"Saves the JSON Schema to the specified file"}},{id:"validator_class",title:"Validator Class (PRIMARY INTERFACE)",description:"⭐ PRIMARY: Use Validator class for all validation - best performance and flexibility",method:"Validator(contract_dir=None, contract_file=None, contract_dict=None, contract_metadata=None, store=None, schema_id=None, schema_version=None)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import Validator, create_validator
216
+ from pycharter.metadata_store import SQLiteMetadataStore
217
+
218
+ # From contract directory
219
+ validator = Validator(contract_dir="data/contracts/user")
220
+ result = validator.validate({"name": "Alice", "age": 30})
221
+
222
+ # From metadata store
223
+ store = SQLiteMetadataStore("metadata.db")
224
+ store.connect()
225
+ validator = Validator(store=store, schema_id="user_schema")
226
+ result = validator.validate({"name": "Alice", "age": 30})
227
+
228
+ # From contract file
229
+ validator = Validator(contract_file="contracts/user.yaml")
230
+ result = validator.validate({"name": "Alice", "age": 30})
231
+
232
+ # Batch validation
233
+ results = validator.validate_batch([
234
+ {"name": "Alice", "age": 30},
235
+ {"name": "Bob", "age": 25}
236
+ ])
237
+
238
+ # Factory function
239
+ validator = create_validator(contract_file="contract.yaml")`,arguments:[{name:"contract_dir",type:"Optional[str]",description:"Directory containing contract files (schema.yaml, coercion_rules.yaml, validation_rules.yaml)",required:!1},{name:"contract_file",type:"Optional[str]",description:"Path to complete contract file (YAML/JSON)",required:!1},{name:"contract_dict",type:"Optional[Dict[str, Any]]",description:"Contract as dictionary with schema, coercion_rules, validation_rules keys",required:!1},{name:"contract_metadata",type:"Optional[ContractMetadata]",description:"ContractMetadata object (from parse_contract)",required:!1},{name:"store",type:"Optional[MetadataStoreClient]",description:"MetadataStoreClient instance (for loading from metadata store)",required:!1},{name:"schema_id",type:"Optional[str]",description:"Schema identifier (required when using store)",required:!1},{name:"schema_version",type:"Optional[str]",description:"Optional schema version (defaults to latest when using store)",required:!1}],returns:{type:"Validator",description:"Validator instance with validate() and validate_batch() methods"}},{id:"validate_with_store",title:"Validate with Store (Convenience)",description:"Quick validation using schema from metadata store",method:"validate_with_store(store, schema_id, data, version=None, strict=False)",apiEndpoint:"/api/v1/validation/validate",apiMethod:"POST",exampleRequest:{schema_id:"user_schema",data:{name:"Alice",age:30},version:"1.0.0",strict:!1},exampleCode:`from pycharter import validate_with_store
240
+ from pycharter.metadata_store import SQLiteMetadataStore
241
+
242
+ store = SQLiteMetadataStore("metadata.db")
243
+ store.connect()
244
+
245
+ result = validate_with_store(
246
+ store=store,
247
+ schema_id="user_schema",
248
+ data={"name": "Alice", "age": 30},
249
+ version="1.0.0"
250
+ )
251
+
252
+ if result.is_valid:
253
+ print("Valid data:", result.data)
254
+ else:
255
+ print("Errors:", result.errors)`,arguments:[{name:"store",type:"MetadataStoreClient",description:"MetadataStoreClient instance",required:!0},{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"data",type:"Dict[str, Any]",description:"Data dictionary to validate",required:!0},{name:"version",type:"Optional[str]",description:"Optional schema version (if None, uses latest)",required:!1,default:"None"},{name:"strict",type:"bool",description:"If True, raise exceptions on validation errors",required:!1,default:"False"}],returns:{type:"ValidationResult",description:"ValidationResult object with is_valid flag, validated data (if valid), and list of errors (if invalid)"}},{id:"validate_with_contract",title:"Validate with Contract (Convenience)",description:"Quick validation using contract dictionary or file",method:"validate_with_contract(contract, data, strict=False)",apiEndpoint:"/api/v1/validation/validate",apiMethod:"POST",exampleRequest:{contract:{schema:{type:"object",properties:{name:{type:"string"},age:{type:"integer"}}}},data:{name:"Alice",age:30},strict:!1},exampleCode:`from pycharter import validate_with_contract
256
+
257
+ contract = {
258
+ "schema": {
259
+ "type": "object",
260
+ "properties": {
261
+ "name": {"type": "string"},
262
+ "age": {"type": "integer"}
263
+ }
264
+ }
265
+ }
266
+
267
+ result = validate_with_contract(
268
+ contract=contract,
269
+ data={"name": "Alice", "age": 30}
270
+ )
271
+
272
+ # Or from file
273
+ result = validate_with_contract(
274
+ contract="contracts/user.yaml",
275
+ data={"name": "Alice", "age": 30}
276
+ )`,arguments:[{name:"contract",type:"Dict[str, Any] | ContractMetadata | str",description:"Contract dictionary, ContractMetadata object, or file path",required:!0},{name:"data",type:"Dict[str, Any]",description:"Data dictionary to validate",required:!0},{name:"strict",type:"bool",description:"If True, raise exceptions on validation errors",required:!1,default:"False"}],returns:{type:"ValidationResult",description:"ValidationResult object with is_valid flag, validated data (if valid), and list of errors (if invalid)"}},{id:"validate_batch_with_store",title:"Batch Validate with Store",description:"Validate multiple records using schema from metadata store",method:"validate_batch_with_store(store, schema_id, data_list, version=None, strict=False)",apiEndpoint:"/api/v1/validation/validate-batch",apiMethod:"POST",exampleRequest:{schema_id:"user_schema",data_list:[{name:"Alice",age:30},{name:"Bob",age:25}],version:"1.0.0",strict:!1},exampleCode:`from pycharter import validate_batch_with_store
277
+ from pycharter.metadata_store import SQLiteMetadataStore
278
+
279
+ store = SQLiteMetadataStore("metadata.db")
280
+ store.connect()
281
+
282
+ results = validate_batch_with_store(
283
+ store=store,
284
+ schema_id="user_schema",
285
+ data_list=[
286
+ {"name": "Alice", "age": 30},
287
+ {"name": "Bob", "age": 25}
288
+ ],
289
+ version="1.0.0"
290
+ )
291
+
292
+ print(f"Valid: {results.total_count - len(results.errors)}/{results.total_count}")`,arguments:[{name:"store",type:"MetadataStoreClient",description:"MetadataStoreClient instance",required:!0},{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"data_list",type:"List[Dict[str, Any]]",description:"List of data dictionaries to validate",required:!0},{name:"version",type:"Optional[str]",description:"Optional schema version (if None, uses latest)",required:!1,default:"None"},{name:"strict",type:"bool",description:"If True, raise exceptions on validation errors",required:!1,default:"False"}],returns:{type:"ValidationBatchResponse",description:"Batch validation results with total_count, valid_count, error_count, and results list"}},{id:"validate_batch_with_contract",title:"Batch Validate with Contract",description:"Validate multiple records using contract dictionary or file",method:"validate_batch_with_contract(contract, data_list, strict=False)",apiEndpoint:"/api/v1/validation/validate-batch",apiMethod:"POST",exampleRequest:{contract:{schema:{type:"object",properties:{name:{type:"string"},age:{type:"integer"}}}},data_list:[{name:"Alice",age:30},{name:"Bob",age:25}],strict:!1},exampleCode:`from pycharter import validate_batch_with_contract
293
+
294
+ contract = {
295
+ "schema": {
296
+ "type": "object",
297
+ "properties": {
298
+ "name": {"type": "string"},
299
+ "age": {"type": "integer"}
300
+ }
301
+ }
302
+ }
303
+
304
+ results = validate_batch_with_contract(
305
+ contract=contract,
306
+ data_list=[
307
+ {"name": "Alice", "age": 30},
308
+ {"name": "Bob", "age": 25}
309
+ ]
310
+ )`,arguments:[{name:"contract",type:"Dict[str, Any] | ContractMetadata | str",description:"Contract dictionary, ContractMetadata object, or file path",required:!0},{name:"data_list",type:"List[Dict[str, Any]]",description:"List of data dictionaries to validate",required:!0},{name:"strict",type:"bool",description:"If True, raise exceptions on validation errors",required:!1,default:"False"}],returns:{type:"ValidationBatchResponse",description:"Batch validation results with total_count, valid_count, error_count, and results list"}},{id:"get_model_from_store",title:"Get Model from Store",description:"Get Pydantic model class from schema stored in metadata store",method:"get_model_from_store(store, schema_id, version=None)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import get_model_from_store
311
+ from pycharter.metadata_store import SQLiteMetadataStore
312
+
313
+ store = SQLiteMetadataStore("metadata.db")
314
+ store.connect()
315
+
316
+ # Get Pydantic model class
317
+ UserModel = get_model_from_store(
318
+ store=store,
319
+ schema_id="user_schema",
320
+ version="1.0.0"
321
+ )
322
+
323
+ # Use the model directly
324
+ user = UserModel(name="Alice", age=30)
325
+ print(user.model_dump())`,arguments:[{name:"store",type:"MetadataStoreClient",description:"MetadataStoreClient instance",required:!0},{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"version",type:"Optional[str]",description:"Optional schema version (if None, uses latest)",required:!1,default:"None"}],returns:{type:"Type[BaseModel]",description:"Pydantic model class generated from the schema"}},{id:"get_model_from_contract",title:"Get Model from Contract",description:"Get Pydantic model class from contract dictionary or file",method:"get_model_from_contract(contract)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import get_model_from_contract
326
+
327
+ contract = {
328
+ "schema": {
329
+ "type": "object",
330
+ "properties": {
331
+ "name": {"type": "string"},
332
+ "age": {"type": "integer"}
333
+ }
334
+ }
335
+ }
336
+
337
+ # Get Pydantic model class
338
+ UserModel = get_model_from_contract(contract)
339
+
340
+ # Use the model directly
341
+ user = UserModel(name="Alice", age=30)
342
+ print(user.model_dump())
343
+
344
+ # Or from file
345
+ UserModel = get_model_from_contract("contracts/user.yaml")`,arguments:[{name:"contract",type:"Dict[str, Any] | ContractMetadata | str",description:"Contract dictionary, ContractMetadata object, or file path",required:!0}],returns:{type:"Type[BaseModel]",description:"Pydantic model class generated from the contract schema"}},{id:"validate",title:"Validate (Low-level)",description:"Low-level validation with existing Pydantic model",method:"validate(data, model, coercion_rules=None, validation_rules=None, strict=False)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import validate
346
+ from pydantic import BaseModel
347
+
348
+ # Define model manually or get from contract
349
+ class UserModel(BaseModel):
350
+ name: str
351
+ age: int
352
+
353
+ # Validate with model
354
+ result = validate(
355
+ data={"name": "Alice", "age": 30},
356
+ model=UserModel,
357
+ coercion_rules=None,
358
+ validation_rules=None
359
+ )
360
+
361
+ if result.is_valid:
362
+ print("Valid:", result.data)
363
+ else:
364
+ print("Errors:", result.errors)`,arguments:[{name:"data",type:"Dict[str, Any]",description:"Data dictionary to validate",required:!0},{name:"model",type:"Type[BaseModel]",description:"Pydantic model class",required:!0},{name:"coercion_rules",type:"Optional[Dict[str, Any]]",description:"Optional coercion rules dictionary",required:!1,default:"None"},{name:"validation_rules",type:"Optional[Dict[str, Any]]",description:"Optional validation rules dictionary",required:!1,default:"None"},{name:"strict",type:"bool",description:"If True, raise exceptions on validation errors",required:!1,default:"False"}],returns:{type:"ValidationResult",description:"ValidationResult object with is_valid flag, validated data (if valid), and list of errors (if invalid)"}},{id:"validate_batch",title:"Batch Validate (Low-level)",description:"Low-level batch validation with existing Pydantic model",method:"validate_batch(data_list, model, coercion_rules=None, validation_rules=None, strict=False)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import validate_batch
365
+ from pydantic import BaseModel
366
+
367
+ # Define model manually or get from contract
368
+ class UserModel(BaseModel):
369
+ name: str
370
+ age: int
371
+
372
+ # Batch validate with model
373
+ results = validate_batch(
374
+ data_list=[
375
+ {"name": "Alice", "age": 30},
376
+ {"name": "Bob", "age": 25}
377
+ ],
378
+ model=UserModel
379
+ )
380
+
381
+ print(f"Valid: {results.valid_count}/{results.total_count}")`,arguments:[{name:"data_list",type:"List[Dict[str, Any]]",description:"List of data dictionaries to validate",required:!0},{name:"model",type:"Type[BaseModel]",description:"Pydantic model class",required:!0},{name:"coercion_rules",type:"Optional[Dict[str, Any]]",description:"Optional coercion rules dictionary",required:!1,default:"None"},{name:"validation_rules",type:"Optional[Dict[str, Any]]",description:"Optional validation rules dictionary",required:!1,default:"None"},{name:"strict",type:"bool",description:"If True, raise exceptions on validation errors",required:!1,default:"False"}],returns:{type:"ValidationBatchResponse",description:"Batch validation results with total_count, valid_count, error_count, and results list"}},{id:"quality_check",title:"QualityCheck Class (PRIMARY INTERFACE)",description:"⭐ PRIMARY: Use QualityCheck class for quality assurance - monitor data quality, calculate metrics, and track violations",method:"QualityCheck(store=None, db_session=None).run(schema_id=None, contract=None, data=None, options=None)",apiEndpoint:"/api/v1/quality/check",apiMethod:"POST",exampleRequest:{schema_id:"user_schema",data:[{name:"Alice",age:30},{name:"Bob",age:25}],calculate_metrics:!0,record_violations:!0},exampleCode:`from pycharter import QualityCheck, QualityCheckOptions, QualityReport, QualityThresholds
382
+ from pycharter.metadata_store import SQLiteMetadataStore
383
+ from sqlalchemy.orm import Session
384
+
385
+ # Create quality check instance
386
+ store = SQLiteMetadataStore("metadata.db")
387
+ store.connect()
388
+ db_session = Session() # Your database session
389
+
390
+ check = QualityCheck(store=store, db_session=db_session)
391
+
392
+ # Configure options
393
+ options = QualityCheckOptions(
394
+ record_violations=True,
395
+ calculate_metrics=True,
396
+ check_thresholds=True,
397
+ include_field_metrics=True,
398
+ sample_size=None # Process all data
399
+ )
400
+
401
+ # Set thresholds (optional)
402
+ thresholds = QualityThresholds(
403
+ overall_score_min=80.0,
404
+ accuracy_min=95.0,
405
+ completeness_min=90.0
406
+ )
407
+
408
+ # Run quality check
409
+ report = check.run(
410
+ schema_id='user_schema',
411
+ data="data/users.json", # File path, list, or callable
412
+ options=options
413
+ )
414
+
415
+ # Access results
416
+ print(f"Quality Score: {report.quality_score.overall_score:.2f}/100")
417
+ print(f"Passed: {report.passed}")
418
+ print(f"Metrics: {report.metrics}")
419
+ print(f"Violations: {len(report.violations)}")`,arguments:[{name:"store",type:"Optional[MetadataStoreClient]",description:"Optional metadata store for retrieving contracts and storing violations",required:!1,default:"None"},{name:"db_session",type:"Optional[Session]",description:"Optional SQLAlchemy database session for persisting metrics and violations",required:!1,default:"None"},{name:"schema_id",type:"Optional[str]",description:"Schema ID (if using store-based validation)",required:!1},{name:"contract",type:"Optional[Dict[str, Any] | str]",description:"Contract dictionary or file path (if using contract-based validation)",required:!1},{name:"data",type:"List[Dict[str, Any]] | str | Callable",description:"Data to validate. Can be a list of dictionaries, file path (JSON/CSV), or callable that returns data",required:!0},{name:"options",type:"Optional[QualityCheckOptions]",description:"Quality check options including record_violations, calculate_metrics, check_thresholds, include_field_metrics, sample_size, data_source, data_version, etc.",required:!1,default:"None"}],returns:{type:"QualityReport",description:"QualityReport object containing validation results, quality score (QualityScore), field metrics (FieldQualityMetrics), violations (List[ViolationRecord]), and threshold breaches"}},{id:"quality_check_options",title:"QualityCheckOptions",description:"Configuration options for quality checks",method:"QualityCheckOptions(record_violations=True, calculate_metrics=True, check_thresholds=False, include_field_metrics=True, sample_size=None, data_source=None, data_version=None, skip_if_unchanged=False)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import QualityCheckOptions
420
+
421
+ options = QualityCheckOptions(
422
+ record_violations=True, # Record violations to database
423
+ calculate_metrics=True, # Calculate quality metrics
424
+ check_thresholds=False, # Check against quality thresholds
425
+ include_field_metrics=True, # Include field-level metrics
426
+ sample_size=1000, # Sample size for large datasets
427
+ data_source="users.csv", # Data source identifier
428
+ data_version="v1.0", # Data version identifier
429
+ skip_if_unchanged=True # Skip if data hasn't changed
430
+ )`,arguments:[{name:"record_violations",type:"bool",description:"Whether to record violations to database",required:!1,default:"True"},{name:"calculate_metrics",type:"bool",description:"Whether to calculate quality metrics",required:!1,default:"True"},{name:"check_thresholds",type:"bool",description:"Whether to check against quality thresholds",required:!1,default:"False"},{name:"include_field_metrics",type:"bool",description:"Whether to include field-level quality metrics",required:!1,default:"True"},{name:"sample_size",type:"Optional[int]",description:"Sample size for large datasets (None = process all)",required:!1,default:"None"},{name:"data_source",type:"Optional[str]",description:"Data source identifier (e.g., file name)",required:!1,default:"None"},{name:"data_version",type:"Optional[str]",description:"Data version identifier",required:!1,default:"None"},{name:"skip_if_unchanged",type:"bool",description:"Skip quality check if data fingerprint hasn't changed",required:!1,default:"False"}],returns:{type:"QualityCheckOptions",description:"QualityCheckOptions instance for configuring quality checks"}},{id:"quality_thresholds",title:"QualityThresholds",description:"Define quality thresholds for monitoring and alerting",method:"QualityThresholds(overall_score_min=None, accuracy_min=None, completeness_min=None, violation_rate_max=None, field_thresholds=None)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import QualityThresholds
431
+
432
+ thresholds = QualityThresholds(
433
+ overall_score_min=80.0, # Minimum overall quality score
434
+ accuracy_min=95.0, # Minimum accuracy percentage
435
+ completeness_min=90.0, # Minimum completeness percentage
436
+ violation_rate_max=0.05, # Maximum violation rate (5%)
437
+ field_thresholds={ # Field-specific thresholds
438
+ "email": {"completeness_min": 98.0},
439
+ "age": {"accuracy_min": 99.0}
440
+ }
441
+ )`,arguments:[{name:"overall_score_min",type:"Optional[float]",description:"Minimum overall quality score (0-100)",required:!1,default:"None"},{name:"accuracy_min",type:"Optional[float]",description:"Minimum accuracy percentage (0-100)",required:!1,default:"None"},{name:"completeness_min",type:"Optional[float]",description:"Minimum completeness percentage (0-100)",required:!1,default:"None"},{name:"violation_rate_max",type:"Optional[float]",description:"Maximum violation rate (0-1)",required:!1,default:"None"},{name:"field_thresholds",type:"Optional[Dict[str, Dict[str, float]]]",description:'Field-specific thresholds (e.g., {"email": {"completeness_min": 98.0}})',required:!1,default:"None"}],returns:{type:"QualityThresholds",description:"QualityThresholds instance for defining quality requirements"}}];function f({method:o}){let[d,c]=(0,a.useState)(o.exampleRequest?JSON.stringify(o.exampleRequest,null,2):""),[m,p]=(0,a.useState)(null),[u,h]=(0,a.useState)(null),[_,f]=(0,a.useState)(!1),[y,v]=(0,a.useState)(!1);if(!o.apiEndpoint)return null;let g=o.apiEndpoint?.includes("/upload")??!1,x=async()=>{f(!0),h(null);try{let t,a,{getApiBaseUrl:i}=await e.A(36909),r=i(),s=o.apiEndpoint;if(!s){h({success:!1,error:"This method does not have an API endpoint (Python-only)"}),f(!1);return}s.includes("{schema_id}")&&(s=s.replace("{schema_id}","user_schema"));let n=`${r}${s}`;if("GET"===o.apiMethod)t=await fetch(n);else if(g){if(!m){h({success:!1,error:"Please select a file to upload"}),f(!1);return}let e=new FormData;e.append("file",m),s.includes("/contracts/parse/upload")&&e.append("validate","true"),t=await fetch(n,{method:o.apiMethod,body:e})}else{let e=d?JSON.parse(d):{};t=await fetch(n,{method:o.apiMethod,headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}let l=t.headers.get("content-type");a=l&&l.includes("application/json")?await t.json():{message:await t.text()},t.ok?h({success:!0,data:a}):h({success:!1,error:a.detail||a.message||`HTTP ${t.status}: ${t.statusText}`})}catch(t){let e=t.message;e.includes("JSON")&&(e="Invalid JSON in request body. Please check your input."),h({success:!1,error:e||"Failed to test API"})}finally{f(!1)}};return(0,t.jsxs)("div",{className:"border rounded-lg p-4 bg-muted/30",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-3",children:[(0,t.jsx)("h5",{className:"text-sm font-semibold",children:"Test API"}),o.apiEndpoint&&(0,t.jsxs)("div",{className:"flex gap-2",children:[(0,t.jsx)(i.Button,{size:"sm",variant:"outline",onClick:()=>{var e;return o.apiEndpoint&&(e=o.apiEndpoint,void(navigator.clipboard.writeText(e),v(!0),setTimeout(()=>v(!1),2e3)))},className:"h-7",disabled:!o.apiEndpoint,children:y?(0,t.jsx)(l,{className:"h-3 w-3"}):(0,t.jsx)(n,{className:"h-3 w-3"})}),(0,t.jsx)(i.Button,{size:"sm",onClick:x,disabled:_||"GET"!==o.apiMethod&&!g&&!d||g&&!m,className:"h-7",children:_?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("div",{className:"mr-1",children:(0,t.jsx)(r.default,{size:"sm"})}),"Testing..."]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s,{className:"h-3 w-3 mr-1"}),"Test"]})})]})]}),o.apiEndpoint&&"GET"!==o.apiMethod&&(0,t.jsx)("div",{className:"mb-3",children:g?(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs font-medium mb-1",children:"Upload File"}),(0,t.jsx)("input",{type:"file",accept:".yaml,.yml,.json",onChange:e=>p(e.target.files?.[0]||null),className:"w-full px-2 py-1 border rounded text-xs bg-background"}),m&&(0,t.jsxs)("div",{className:"mt-1 text-xs text-muted-foreground",children:["Selected: ",m.name," (",(m.size/1024).toFixed(2)," KB)"]})]}):(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs font-medium mb-1",children:"Request Body (JSON)"}),(0,t.jsx)("textarea",{value:d,onChange:e=>c(e.target.value),rows:6,className:"w-full px-2 py-1 border rounded text-xs font-mono bg-background",placeholder:"Enter JSON request body..."})]})}),o.apiEndpoint&&(0,t.jsxs)("div",{className:"text-xs text-muted-foreground mb-2",children:[(0,t.jsx)("span",{className:"font-mono font-semibold",children:o.apiMethod})," ",o.apiEndpoint]}),u&&(0,t.jsx)("div",{className:"mt-3",children:u.success?(0,t.jsxs)("div",{className:"bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded p-2",children:[(0,t.jsx)("div",{className:"text-xs font-semibold text-green-800 dark:text-green-200 mb-1",children:"Success"}),(0,t.jsx)("pre",{className:"text-xs overflow-x-auto text-green-700 dark:text-green-300",children:JSON.stringify(u.data,null,2)})]}):(0,t.jsxs)("div",{className:"bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded p-2",children:[(0,t.jsx)("div",{className:"text-xs font-semibold text-red-800 dark:text-red-200 mb-1",children:"Error"}),(0,t.jsx)("div",{className:"text-xs text-red-700 dark:text-red-300",children:u.error})]})})]})}function y(){let[e,i]=(0,a.useState)("contract-management"),r={"contract-management":["parse_contract","parse_contract_file","build_contract","build_contract_from_store"],"metadata-store":["store_schema","get_schema","list_schemas","store_metadata","get_metadata","store_coercion_rules","get_coercion_rules","store_validation_rules","get_validation_rules","get_complete_schema"],"model-generator":["generate_model","generate_model_file","from_dict","from_file","from_json","from_url","model_to_schema","to_dict","to_json","to_file"],validation:["validator_class","validate_with_store","validate_with_contract","validate_batch_with_store","validate_batch_with_contract","get_model_from_store","get_model_from_contract","validate","validate_batch"],"quality-assurance":["quality_check","quality_check_options","quality_thresholds"]},o=e=>{let t=Object.keys(r).find(t=>r[t].includes(e));if(t)i(t),setTimeout(()=>{let t=document.getElementById(`method-${e}`);t&&t.scrollIntoView({behavior:"smooth",block:"start"})},150);else{let t=document.getElementById(`method-${e}`);t&&t.scrollIntoView({behavior:"smooth",block:"start"})}},s=[{id:"contract-management",title:"Contract Management",icon:d.FileText,items:[{id:"parse_contract",label:"Parse Contract",onClick:()=>o("parse_contract")},{id:"build_contract",label:"Build Contract",onClick:()=>o("build_contract")}]},{id:"metadata-store",title:"Metadata Store Client",icon:c.Database,items:[{id:"store_schema",label:"Store Schema",onClick:()=>o("store_schema")},{id:"get_schema",label:"Get Schema",onClick:()=>o("get_schema")},{id:"list_schemas",label:"List Schemas",onClick:()=>o("list_schemas")},{id:"store_metadata",label:"Store Metadata",onClick:()=>o("store_metadata")},{id:"get_metadata",label:"Get Metadata",onClick:()=>o("get_metadata")},{id:"store_coercion_rules",label:"Store Coercion Rules",onClick:()=>o("store_coercion_rules")},{id:"get_coercion_rules",label:"Get Coercion Rules",onClick:()=>o("get_coercion_rules")},{id:"store_validation_rules",label:"Store Validation Rules",onClick:()=>o("store_validation_rules")},{id:"get_validation_rules",label:"Get Validation Rules",onClick:()=>o("get_validation_rules")},{id:"get_complete_schema",label:"Get Complete Schema",onClick:()=>o("get_complete_schema")}]},{id:"model-generator",title:"Model Generator",icon:m,items:[{id:"generate_model",label:"Generate Model",onClick:()=>o("generate_model")},{id:"generate_model_file",label:"Generate Model File",onClick:()=>o("generate_model_file")},{id:"from_dict",label:"From Dict",onClick:()=>o("from_dict")},{id:"from_file",label:"From File",onClick:()=>o("from_file")},{id:"from_json",label:"From JSON",onClick:()=>o("from_json")},{id:"from_url",label:"From URL",onClick:()=>o("from_url")},{id:"model_to_schema",label:"Model to Schema",onClick:()=>o("model_to_schema")},{id:"to_dict",label:"To Dict",onClick:()=>o("to_dict")},{id:"to_json",label:"To JSON",onClick:()=>o("to_json")},{id:"to_file",label:"To File",onClick:()=>o("to_file")}]},{id:"validation",title:"Validation",icon:p,items:[{id:"validator_class",label:"⭐ Validator Class",onClick:()=>o("validator_class")},{id:"validate_with_store",label:"Validate with Store",onClick:()=>o("validate_with_store")},{id:"validate_with_contract",label:"Validate with Contract",onClick:()=>o("validate_with_contract")},{id:"validate_batch_with_store",label:"Batch Validate (Store)",onClick:()=>o("validate_batch_with_store")},{id:"validate_batch_with_contract",label:"Batch Validate (Contract)",onClick:()=>o("validate_batch_with_contract")},{id:"get_model_from_store",label:"Get Model (Store)",onClick:()=>o("get_model_from_store")},{id:"get_model_from_contract",label:"Get Model (Contract)",onClick:()=>o("get_model_from_contract")},{id:"validate",label:"Validate (Low-level)",onClick:()=>o("validate")},{id:"validate_batch",label:"Batch Validate (Low-level)",onClick:()=>o("validate_batch")}]},{id:"quality-assurance",title:"Quality Assurance",icon:u.Award,items:[{id:"quality_check",label:"⭐ QualityCheck Class",onClick:()=>o("quality_check")},{id:"quality_check_options",label:"QualityCheckOptions",onClick:()=>o("quality_check_options")},{id:"quality_thresholds",label:"QualityThresholds",onClick:()=>o("quality_thresholds")}]}],n=r[e]?_.filter(t=>r[e].includes(t.id)):_;return(0,t.jsxs)("div",{className:"flex h-full bg-background",style:{height:"calc(100vh - 4rem)",overflow:"hidden"},children:[(0,t.jsx)("div",{className:"flex-shrink-0",style:{height:"100%",overflow:"hidden"},children:(0,t.jsx)(h.CollapsibleSidebar,{sections:s,defaultCollapsed:!1,headerTitle:"Documentation",selectedSection:e,onSectionClick:e=>{i(e),setTimeout(()=>{let t=document.getElementById(`section-${e}`);t&&t.scrollIntoView({behavior:"smooth",block:"start"})},100)}})}),(0,t.jsx)("div",{className:"flex-1 min-w-0",style:{height:"100%",overflowY:"auto",overflowX:"hidden"},"data-content-area":!0,children:(0,t.jsx)("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8",children:(0,t.jsxs)("div",{className:"space-y-8",children:[(0,t.jsxs)("div",{id:`section-${e}`,className:"scroll-mt-4 mb-4",children:[(0,t.jsx)("h2",{className:"text-2xl font-bold text-foreground mb-1",children:s.find(t=>t.id===e)?.title||"Documentation"}),(0,t.jsxs)("p",{className:"text-sm text-muted-foreground",children:["contract-management"===e&&"Manage and work with data contracts","metadata-store"===e&&"Store and retrieve schemas, metadata, coercion rules, and validation rules","model-generator"===e&&"Generate Pydantic models from schemas","validation"===e&&"Validate data against schemas and contracts","quality-assurance"===e&&"Monitor data quality and track violations"]})]}),(0,t.jsx)("div",{className:"space-y-6",children:n.map(e=>(0,t.jsx)("div",{id:`method-${e.id}`,className:"border rounded-lg overflow-hidden scroll-mt-4",children:(0,t.jsxs)("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4 p-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h4",{className:"font-semibold mb-2",children:e.title}),(0,t.jsx)("p",{className:"text-sm text-muted-foreground mb-3",children:e.description}),e.arguments&&e.arguments.length>0&&(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsx)("h5",{className:"text-sm font-semibold mb-2",children:"Arguments"}),(0,t.jsx)("div",{className:"space-y-2",children:e.arguments.map((e,a)=>(0,t.jsxs)("div",{className:"text-xs border-l-2 border-primary/20 pl-2",children:[(0,t.jsxs)("div",{className:"font-mono font-semibold text-foreground",children:[e.name,!e.required&&(0,t.jsx)("span",{className:"text-muted-foreground ml-1",children:"(optional)"})]}),(0,t.jsxs)("div",{className:"text-muted-foreground mt-0.5",children:[(0,t.jsx)("span",{className:"font-mono",children:e.type}),e.default&&(0,t.jsxs)("span",{className:"ml-1",children:["default: ",e.default]})]}),(0,t.jsx)("div",{className:"text-muted-foreground mt-1",children:e.description})]},a))})]}),e.returns&&(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsx)("h5",{className:"text-sm font-semibold mb-2",children:"Returns"}),(0,t.jsxs)("div",{className:"text-xs border-l-2 border-green-500/20 pl-2",children:[(0,t.jsx)("div",{className:"font-mono font-semibold text-foreground mb-0.5",children:e.returns.type}),(0,t.jsx)("div",{className:"text-muted-foreground",children:e.returns.description})]})]}),(0,t.jsx)("div",{className:"bg-muted p-3 rounded font-mono text-xs overflow-x-auto mb-3",children:(0,t.jsx)("pre",{className:"whitespace-pre-wrap",children:e.exampleCode})}),(0,t.jsxs)("div",{className:"text-xs text-muted-foreground",children:[(0,t.jsx)("span",{className:"font-semibold",children:"Method:"})," ",e.method]})]}),(0,t.jsx)("div",{children:(0,t.jsx)(f,{method:e})})]})},e.id))}),(0,t.jsxs)("div",{className:"border rounded-lg p-4 bg-primary/5",children:[(0,t.jsx)("h4",{className:"font-semibold mb-2",children:"Additional Resources"}),(0,t.jsxs)("ul",{className:"text-sm space-y-1 text-muted-foreground",children:[(0,t.jsx)("li",{children:"• Full documentation: See README.md and REFERENCE.md"}),(0,t.jsx)("li",{children:"• Examples: Check the examples/ directory"}),(0,t.jsx)("li",{children:"• API Documentation: Available at /docs when running the API server"})]})]})]})})})]})}e.s(["default",()=>y],33558)}]);
@@ -0,0 +1 @@
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,58041,e=>{"use strict";let t=(0,e.i(75254).default)("Database",[["ellipse",{cx:"12",cy:"5",rx:"9",ry:"3",key:"msslwz"}],["path",{d:"M3 5V19A9 3 0 0 0 21 19V5",key:"1wlel7"}],["path",{d:"M3 12A9 3 0 0 0 21 12",key:"mv7ke4"}]]);e.s(["Database",()=>t],58041)},56909,e=>{"use strict";let t=(0,e.i(75254).default)("Save",[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]]);e.s(["Save",()=>t],56909)},37727,7233,e=>{"use strict";var t=e.i(75254);let a=(0,t.default)("X",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);e.s(["X",()=>a],37727);let s=(0,t.default)("Plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);e.s(["Plus",()=>s],7233)},78583,e=>{"use strict";let t=(0,e.i(75254).default)("FileText",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M10 9H8",key:"b1mrlr"}],["path",{d:"M16 13H8",key:"t4e002"}],["path",{d:"M16 17H8",key:"z1uh3a"}]]);e.s(["FileText",()=>t],78583)},46652,e=>{"use strict";var t=e.i(71645),a=e.i(9165);function s(){let[e,s]=(0,t.useState)([]),[r,i]=(0,t.useState)(!0),[l,n]=(0,t.useState)(null),c=(0,t.useCallback)(async()=>{try{i(!0),n(null);let e=await a.api.contracts.list();s(e.contracts)}catch(e){n(e instanceof a.ApiError?e.message:"Failed to load contracts"),console.error("Error loading contracts:",e)}finally{i(!1)}},[]);return(0,t.useEffect)(()=>{c()},[c]),{contracts:e,loading:r,error:l,refetch:c}}e.s(["useContracts",()=>s])},95468,e=>{"use strict";let t=(0,e.i(75254).default)("CircleCheck",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);e.s(["CheckCircle2",()=>t],95468)},98919,52571,e=>{"use strict";var t=e.i(75254);let a=(0,t.default)("Shield",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}]]);e.s(["Shield",()=>a],98919);let s=(0,t.default)("Info",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]]);e.s(["Info",()=>s],52571)},61246,e=>{"use strict";var t=e.i(43476),a=e.i(75157);function s({className:e,...s}){return(0,t.jsx)("div",{className:(0,a.cn)("animate-pulse rounded-md bg-muted",e),...s})}function r({size:e="md",className:s}){return(0,t.jsx)("div",{className:(0,a.cn)("flex items-center justify-center",s),children:(0,t.jsx)("div",{className:(0,a.cn)("animate-spin rounded-full border-2 border-muted border-t-primary",{sm:"h-4 w-4",md:"h-8 w-8",lg:"h-12 w-12"}[e])})})}function i({message:e="Loading..."}){return(0,t.jsx)("div",{className:"min-h-screen flex items-center justify-center bg-background",children:(0,t.jsxs)("div",{className:"text-center",children:[(0,t.jsx)(r,{size:"lg",className:"mb-4"}),(0,t.jsx)("p",{className:"text-muted-foreground",children:e})]})})}function l(){return(0,t.jsxs)("div",{className:"rounded-lg border bg-card p-6 space-y-4",children:[(0,t.jsx)(s,{className:"h-6 w-3/4"}),(0,t.jsx)(s,{className:"h-4 w-full"}),(0,t.jsx)(s,{className:"h-4 w-5/6"}),(0,t.jsxs)("div",{className:"flex gap-2 mt-4",children:[(0,t.jsx)(s,{className:"h-9 w-20"}),(0,t.jsx)(s,{className:"h-9 w-20"})]})]})}function n({rows:e=5}){return(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsx)(s,{className:"h-10 w-full"}),Array.from({length:e}).map((e,a)=>(0,t.jsx)(s,{className:"h-12 w-full"},a))]})}e.s(["CardSkeleton",()=>l,"PageLoading",()=>i,"TableSkeleton",()=>n,"default",()=>r],61246)},43668,e=>{"use strict";var t=e.i(47167);let a="pycharter_settings",s={apiServer:{url:t.default.env.NEXT_PUBLIC_API_URL||"http://localhost:8000"},database:{enabled:!1},dlq:{enabled:!1}};function r(){try{let e=localStorage.getItem(a);if(e){let t=JSON.parse(e);return{...s,...t,apiServer:{...s.apiServer,...t.apiServer},database:{...s.database,...t.database},dlq:{...s.dlq,...t.dlq}}}}catch(e){console.error("Failed to load settings:",e)}return s}function i(e){try{localStorage.setItem(a,JSON.stringify(e))}catch(e){throw console.error("Failed to save settings:",e),e}}function l(){return r().apiServer.url||s.apiServer.url}e.s(["getApiBaseUrl",()=>l,"getSettings",()=>r,"saveSettings",()=>i])},9165,e=>{"use strict";var t=e.i(43668);class a extends Error{status;response;constructor(e,t,a){super(e),this.status=t,this.response=a,this.name="ApiError"}}async function s(e,s){let r=`${(0,t.getApiBaseUrl)()}${e}`;try{let e=await fetch(r,{...s,headers:{"Content-Type":"application/json",...s?.headers}});if(!e.ok){let t;try{t=await e.json()}catch{t={detail:e.statusText}}let s=t.detail||`API request failed: ${e.statusText}`;throw 422===e.status&&t.details&&Array.isArray(t.details)&&(s=t.details.map(e=>{let t=e.loc?.join(".")||e.field||"field",a=e.msg||e.message||"validation error";return`${t}: ${a}`}).join("; ")||s),new a(s,e.status,t)}let t=e.headers.get("content-type");if(t&&t.includes("application/json"))return e.json();return e.text()}catch(s){if(s instanceof TypeError&&"Failed to fetch"===s.message){let s=(0,t.getApiBaseUrl)();throw new a(`Unable to connect to API server at ${s}. Please ensure the API server is running and the URL is correct.`,0,{originalError:"NetworkError",apiUrl:s,endpoint:e,suggestion:"Check your API server settings in the Settings page"})}throw s}}async function r(e){return s(e,{method:"GET"})}async function i(e,t){return s(e,{method:"POST",body:t?JSON.stringify(t):void 0})}async function l(e,t){return s(e,{method:"PUT",body:t?JSON.stringify(t):void 0})}async function n(e,s){let r=`${(0,t.getApiBaseUrl)()}${e}`,i=await fetch(r,{method:"POST",body:s});if(!i.ok){let e;try{e=await i.json()}catch{e={detail:i.statusText}}throw new a(e.detail||`API request failed: ${i.statusText}`,i.status,e)}let l=i.headers.get("content-type");return l&&l.includes("application/json")?i.json():i.text()}async function c(e){let s=`${(0,t.getApiBaseUrl)()}${e}`,r=await fetch(s,{method:"GET"});if(!r.ok){let e;try{e=await r.json()}catch{e={detail:r.statusText}}throw new a(e.detail||`API request failed: ${r.statusText}`,r.status,e)}return r.blob()}e.s(["ApiError",()=>a,"api",0,{contracts:{list:()=>r("/api/v1/contracts"),get:e=>r(`/api/v1/contracts/${e}`),parse:e=>i("/api/v1/contracts/parse",{contract:e}),parseFile:(e,t)=>{let a=new FormData;return a.append("file",e),void 0!==t&&a.append("validate",String(t)),n("/api/v1/contracts/parse/upload",a)},build:e=>i("/api/v1/contracts/build",e),buildFromId:(e,t)=>{let a=new URLSearchParams;t?.include_metadata!==void 0&&a.append("include_metadata",String(t.include_metadata)),t?.include_ownership!==void 0&&a.append("include_ownership",String(t.include_ownership)),t?.include_governance!==void 0&&a.append("include_governance",String(t.include_governance));let s=a.toString();return i(`/api/v1/contracts/${e}/build${s?`?${s}`:""}`,{})},createFromArtifacts:e=>i("/api/v1/contracts/create-from-artifacts",e),createMixed:e=>i("/api/v1/contracts/create-mixed",e),update:(e,t)=>l(`/api/v1/contracts/${e}`,t)},metadata:{listSchemas:()=>r("/api/v1/metadata/schemas"),getSchema:(e,t)=>{let a=t?`?version=${t}`:"";return r(`/api/v1/metadata/schemas/${e}${a}`)},getCompleteSchema:(e,t)=>{let a=t?`?version=${t}`:"";return r(`/api/v1/metadata/schemas/${e}/complete${a}`)},storeSchema:e=>i("/api/v1/metadata/schemas",e),getMetadata:(e,t)=>{let a=t?`?version=${t}`:"";return r(`/api/v1/metadata/metadata/${e}${a}`)},storeMetadata:e=>i("/api/v1/metadata/metadata",e),getCoercionRules:(e,t)=>{let a=t?`?version=${t}`:"";return r(`/api/v1/metadata/coercion-rules/${e}${a}`)},storeCoercionRules:e=>i("/api/v1/metadata/coercion-rules",e),getValidationRules:(e,t)=>{let a=t?`?version=${t}`:"";return r(`/api/v1/metadata/validation-rules/${e}${a}`)},storeValidationRules:e=>i("/api/v1/metadata/validation-rules",e),getEntityList:e=>r(`/api/v1/metadata/${e}`),createEntity:(e,t)=>i(`/api/v1/metadata/${e}`,t),updateEntity:(e,t,a)=>l(`/api/v1/metadata/${e}/${t}`,a),listArtifacts:()=>r("/api/v1/metadata/artifacts")},validation:{validate:e=>i("/api/v1/validation/validate",e),validateBatch:e=>i("/api/v1/validation/validate-batch",e)},schemas:{generate:e=>i("/api/v1/schemas/generate",e),convert:e=>i("/api/v1/schemas/convert",e)},quality:{listMetrics:e=>{let t=new URLSearchParams;e?.schema_id&&t.append("schema_id",e.schema_id),e?.limit&&t.append("limit",e.limit.toString()),e?.offset&&t.append("offset",e.offset.toString());let a=t.toString();return r(`/api/v1/quality/metrics${a?`?${a}`:""}`)},getMetric:e=>r(`/api/v1/quality/metrics/${e}`),getReport:(e,t)=>{let a=new URLSearchParams;t?.data_source&&a.append("data_source",t.data_source),t?.limit&&a.append("limit",t.limit.toString());let s=a.toString();return r(`/api/v1/quality/reports/${e}${s?`?${s}`:""}`)},check:e=>i("/api/v1/quality/check",e),checkUpload:(e,t)=>{let a=new FormData;return a.append("file",e),t.schema_id&&a.append("schema_id",t.schema_id),t.contract&&a.append("contract",t.contract),void 0!==t.record_violations&&a.append("record_violations",String(t.record_violations)),void 0!==t.calculate_metrics&&a.append("calculate_metrics",String(t.calculate_metrics)),void 0!==t.check_thresholds&&a.append("check_thresholds",String(t.check_thresholds)),t.thresholds&&a.append("thresholds",t.thresholds),void 0!==t.include_field_metrics&&a.append("include_field_metrics",String(t.include_field_metrics)),void 0!==t.sample_size&&a.append("sample_size",String(t.sample_size)),t.data_source&&a.append("data_source",t.data_source),t.data_version&&a.append("data_version",t.data_version),n("/api/v1/quality/check/upload",a)},queryViolations:e=>i("/api/v1/quality/violations",e)},templates:{downloadSchema:()=>c("/api/v1/templates/schema"),downloadContractArtifacts:()=>c("/api/v1/templates/contract-artifacts")},settings:{testDatabase:e=>i("/api/v1/settings/test-database",e),testDlq:e=>i("/api/v1/settings/test-dlq",e),getDlqStats:e=>i("/api/v1/settings/dlq-stats",e)}}])},63209,e=>{"use strict";let t=(0,e.i(75254).default)("CircleAlert",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]]);e.s(["AlertCircle",()=>t],63209)},95113,e=>{"use strict";var t=e.i(43476),a=e.i(63209),s=e.i(9165),r=e.i(75157);function i({error:e,title:i="Error",className:l}){if(!e)return null;let n=e instanceof s.ApiError,c=n?e.message:e.message||"An unexpected error occurred";return(0,t.jsx)("div",{className:(0,r.cn)("rounded-lg border border-destructive/50 bg-destructive/10 p-4",l),children:(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsx)(a.AlertCircle,{className:"h-5 w-5 text-destructive flex-shrink-0 mt-0.5"}),(0,t.jsxs)("div",{className:"ml-3",children:[(0,t.jsx)("h3",{className:"text-sm font-medium text-destructive",children:i}),(0,t.jsxs)("div",{className:"mt-2 text-sm text-destructive/90",children:[(0,t.jsx)("p",{children:c}),n&&e.status&&(0,t.jsxs)("p",{className:"mt-1 text-xs opacity-75",children:["Status: ",e.status]})]})]})]})})}e.s(["default",()=>i])},88511,e=>{"use strict";let t=(0,e.i(75254).default)("SquarePen",[["path",{d:"M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7",key:"1m0v6g"}],["path",{d:"M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z",key:"ohrbg2"}]]);e.s(["Edit",()=>t],88511)},40160,e=>{"use strict";let t=(0,e.i(75254).default)("Download",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"7 10 12 15 17 10",key:"2ggqvy"}],["line",{x1:"12",x2:"12",y1:"15",y2:"3",key:"1vk2je"}]]);e.s(["Download",()=>t],40160)}]);