structurize 2.19.0__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.
- avrotize/__init__.py +64 -0
- avrotize/__main__.py +6 -0
- avrotize/_version.py +34 -0
- avrotize/asn1toavro.py +160 -0
- avrotize/avrotize.py +152 -0
- avrotize/avrotocpp.py +483 -0
- avrotize/avrotocsharp.py +1075 -0
- avrotize/avrotocsv.py +121 -0
- avrotize/avrotodatapackage.py +173 -0
- avrotize/avrotodb.py +1383 -0
- avrotize/avrotogo.py +476 -0
- avrotize/avrotographql.py +197 -0
- avrotize/avrotoiceberg.py +210 -0
- avrotize/avrotojava.py +2156 -0
- avrotize/avrotojs.py +250 -0
- avrotize/avrotojsons.py +481 -0
- avrotize/avrotojstruct.py +345 -0
- avrotize/avrotokusto.py +364 -0
- avrotize/avrotomd.py +137 -0
- avrotize/avrotools.py +168 -0
- avrotize/avrotoparquet.py +208 -0
- avrotize/avrotoproto.py +359 -0
- avrotize/avrotopython.py +624 -0
- avrotize/avrotorust.py +435 -0
- avrotize/avrotots.py +598 -0
- avrotize/avrotoxsd.py +344 -0
- avrotize/cddltostructure.py +1841 -0
- avrotize/commands.json +3337 -0
- avrotize/common.py +834 -0
- avrotize/constants.py +72 -0
- avrotize/csvtoavro.py +132 -0
- avrotize/datapackagetoavro.py +76 -0
- avrotize/dependencies/cpp/vcpkg/vcpkg.json +19 -0
- avrotize/dependencies/typescript/node22/package.json +16 -0
- avrotize/dependency_resolver.py +348 -0
- avrotize/dependency_version.py +432 -0
- avrotize/jsonstoavro.py +2167 -0
- avrotize/jsonstostructure.py +2642 -0
- avrotize/jstructtoavro.py +878 -0
- avrotize/kstructtoavro.py +93 -0
- avrotize/kustotoavro.py +455 -0
- avrotize/parquettoavro.py +157 -0
- avrotize/proto2parser.py +498 -0
- avrotize/proto3parser.py +403 -0
- avrotize/prototoavro.py +382 -0
- avrotize/structuretocddl.py +597 -0
- avrotize/structuretocpp.py +697 -0
- avrotize/structuretocsharp.py +2295 -0
- avrotize/structuretocsv.py +365 -0
- avrotize/structuretodatapackage.py +659 -0
- avrotize/structuretodb.py +1125 -0
- avrotize/structuretogo.py +720 -0
- avrotize/structuretographql.py +502 -0
- avrotize/structuretoiceberg.py +355 -0
- avrotize/structuretojava.py +853 -0
- avrotize/structuretojsons.py +498 -0
- avrotize/structuretokusto.py +639 -0
- avrotize/structuretomd.py +322 -0
- avrotize/structuretoproto.py +764 -0
- avrotize/structuretopython.py +772 -0
- avrotize/structuretorust.py +714 -0
- avrotize/structuretots.py +653 -0
- avrotize/structuretoxsd.py +679 -0
- avrotize/xsdtoavro.py +413 -0
- structurize-2.19.0.dist-info/METADATA +107 -0
- structurize-2.19.0.dist-info/RECORD +70 -0
- structurize-2.19.0.dist-info/WHEEL +5 -0
- structurize-2.19.0.dist-info/entry_points.txt +2 -0
- structurize-2.19.0.dist-info/licenses/LICENSE +201 -0
- structurize-2.19.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
"""
|
|
3
|
+
Module to convert JSON Structure schema to Markdown documentation.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import os
|
|
8
|
+
from typing import Any, Dict, List, Union
|
|
9
|
+
|
|
10
|
+
from avrotize.common import render_template
|
|
11
|
+
|
|
12
|
+
class StructureToMarkdownConverter:
|
|
13
|
+
"""
|
|
14
|
+
Class to convert JSON Structure schema to Markdown documentation.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, structure_schema_path: str, markdown_path: str):
|
|
18
|
+
"""
|
|
19
|
+
Initialize the converter with file paths.
|
|
20
|
+
|
|
21
|
+
:param structure_schema_path: Path to the JSON Structure schema file.
|
|
22
|
+
:param markdown_path: Path to save the Markdown file.
|
|
23
|
+
"""
|
|
24
|
+
self.structure_schema_path = structure_schema_path
|
|
25
|
+
self.markdown_path = markdown_path
|
|
26
|
+
self.objects = {}
|
|
27
|
+
self.choices = {}
|
|
28
|
+
self.enums = {}
|
|
29
|
+
self.definitions = {}
|
|
30
|
+
|
|
31
|
+
def convert(self):
|
|
32
|
+
"""
|
|
33
|
+
Convert JSON Structure schema to Markdown and save to file.
|
|
34
|
+
"""
|
|
35
|
+
with open(self.structure_schema_path, 'r', encoding='utf-8') as file:
|
|
36
|
+
structure_schema = json.load(file)
|
|
37
|
+
|
|
38
|
+
schema_name = os.path.splitext(os.path.basename(self.structure_schema_path))[0]
|
|
39
|
+
|
|
40
|
+
# Process the schema
|
|
41
|
+
self.process_schema(structure_schema)
|
|
42
|
+
|
|
43
|
+
# Generate markdown
|
|
44
|
+
self.generate_markdown(schema_name, structure_schema)
|
|
45
|
+
|
|
46
|
+
def process_schema(self, schema: Dict[str, Any], parent_namespace: str = ''):
|
|
47
|
+
"""
|
|
48
|
+
Process the schema to extract all named types.
|
|
49
|
+
|
|
50
|
+
:param schema: The schema or sub-schema to process
|
|
51
|
+
:param parent_namespace: The parent namespace
|
|
52
|
+
"""
|
|
53
|
+
# Store definitions separately
|
|
54
|
+
if 'definitions' in schema:
|
|
55
|
+
self.definitions = schema['definitions']
|
|
56
|
+
|
|
57
|
+
# Process root schema (but not definitions)
|
|
58
|
+
if 'type' in schema:
|
|
59
|
+
name = schema.get('name', 'Root')
|
|
60
|
+
self.extract_named_types(schema, parent_namespace, name, skip_definitions=True)
|
|
61
|
+
|
|
62
|
+
def extract_named_types(self, schema: Union[Dict, List, str], parent_namespace: str = '', type_name: str = '', skip_definitions: bool = False):
|
|
63
|
+
"""
|
|
64
|
+
Extract all named types (objects, choices, enums) from the schema.
|
|
65
|
+
|
|
66
|
+
:param schema: Schema element to process
|
|
67
|
+
:param parent_namespace: Parent namespace
|
|
68
|
+
:param type_name: Name of this type
|
|
69
|
+
:param skip_definitions: Skip processing definitions (they're handled separately)
|
|
70
|
+
"""
|
|
71
|
+
if isinstance(schema, dict):
|
|
72
|
+
# Skip definitions section when processing root schema
|
|
73
|
+
if skip_definitions and 'definitions' in schema:
|
|
74
|
+
# Create a copy without definitions for processing
|
|
75
|
+
schema = {k: v for k, v in schema.items() if k != 'definitions'}
|
|
76
|
+
|
|
77
|
+
schema_type = schema.get('type')
|
|
78
|
+
ns = schema.get('namespace', parent_namespace)
|
|
79
|
+
name = schema.get('name', type_name)
|
|
80
|
+
|
|
81
|
+
# Only add named objects and choices to the respective lists
|
|
82
|
+
# Inline/anonymous objects should not be listed separately
|
|
83
|
+
if schema_type == 'object' and 'name' in schema:
|
|
84
|
+
self.objects.setdefault(ns, []).append(schema)
|
|
85
|
+
elif schema_type == 'choice' and 'name' in schema:
|
|
86
|
+
self.choices.setdefault(ns, []).append(schema)
|
|
87
|
+
elif 'enum' in schema:
|
|
88
|
+
# Handle enum constraint
|
|
89
|
+
self.enums.setdefault(ns, []).append({
|
|
90
|
+
'name': name,
|
|
91
|
+
'values': schema['enum'],
|
|
92
|
+
'doc': schema.get('description', '')
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
# Recursively process properties
|
|
96
|
+
if 'properties' in schema:
|
|
97
|
+
for prop_name, prop_schema in schema['properties'].items():
|
|
98
|
+
self.extract_named_types(prop_schema, ns, prop_name)
|
|
99
|
+
|
|
100
|
+
# Process items in arrays/sets
|
|
101
|
+
if 'items' in schema:
|
|
102
|
+
self.extract_named_types(schema['items'], ns)
|
|
103
|
+
|
|
104
|
+
# Process values in maps
|
|
105
|
+
if 'values' in schema:
|
|
106
|
+
self.extract_named_types(schema['values'], ns)
|
|
107
|
+
|
|
108
|
+
# Process choice alternatives
|
|
109
|
+
if 'choices' in schema:
|
|
110
|
+
choices = schema['choices']
|
|
111
|
+
if isinstance(choices, dict):
|
|
112
|
+
for choice_name, choice_schema in choices.items():
|
|
113
|
+
self.extract_named_types(choice_schema, ns, choice_name)
|
|
114
|
+
elif isinstance(choices, list):
|
|
115
|
+
for choice_schema in choices:
|
|
116
|
+
self.extract_named_types(choice_schema, ns)
|
|
117
|
+
|
|
118
|
+
elif isinstance(schema, list):
|
|
119
|
+
# Union type
|
|
120
|
+
for sub_schema in schema:
|
|
121
|
+
self.extract_named_types(sub_schema, parent_namespace)
|
|
122
|
+
|
|
123
|
+
def generate_markdown(self, schema_name: str, root_schema: Dict[str, Any]):
|
|
124
|
+
"""
|
|
125
|
+
Generate markdown content from the extracted types using Jinja2 template.
|
|
126
|
+
|
|
127
|
+
:param schema_name: The name of the schema file.
|
|
128
|
+
:param root_schema: The root schema object
|
|
129
|
+
"""
|
|
130
|
+
render_template("structuretomd/README.md.jinja", self.markdown_path,
|
|
131
|
+
schema_name=schema_name,
|
|
132
|
+
schema_description=root_schema.get('description', ''),
|
|
133
|
+
schema_id=root_schema.get('$id', ''),
|
|
134
|
+
schema_uses=root_schema.get('$uses', []),
|
|
135
|
+
schema_offers=root_schema.get('$offers', {}),
|
|
136
|
+
objects=self.objects,
|
|
137
|
+
choices=self.choices,
|
|
138
|
+
enums=self.enums,
|
|
139
|
+
definitions=self.definitions,
|
|
140
|
+
generate_property_markdown=self.generate_property_markdown,
|
|
141
|
+
get_type_string=self.get_type_string
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
def generate_property_markdown(self, prop_name: str, prop_schema: Union[Dict, List, str], required: bool = False) -> str:
|
|
145
|
+
"""
|
|
146
|
+
Generate markdown content for a single property.
|
|
147
|
+
|
|
148
|
+
:param prop_name: Property name
|
|
149
|
+
:param prop_schema: Property schema
|
|
150
|
+
:param required: Whether the property is required
|
|
151
|
+
:return: Markdown content as a string
|
|
152
|
+
"""
|
|
153
|
+
lines = []
|
|
154
|
+
type_str = self.get_type_string(prop_schema)
|
|
155
|
+
required_str = " (required)" if required else ""
|
|
156
|
+
|
|
157
|
+
lines.append(f"- **{prop_name}**{required_str}: {type_str}")
|
|
158
|
+
|
|
159
|
+
# Add description if present
|
|
160
|
+
if isinstance(prop_schema, dict):
|
|
161
|
+
if 'description' in prop_schema:
|
|
162
|
+
lines.append(f" - Description: {prop_schema['description']}")
|
|
163
|
+
|
|
164
|
+
# Add extension properties (from various JSON Structure extension specs)
|
|
165
|
+
extensions = []
|
|
166
|
+
|
|
167
|
+
# Alternate names (JSONStructureAlternateNames extension)
|
|
168
|
+
if 'altnames' in prop_schema:
|
|
169
|
+
altnames = prop_schema['altnames']
|
|
170
|
+
if isinstance(altnames, dict):
|
|
171
|
+
altnames_list = [f"{k}: {v}" for k, v in altnames.items()]
|
|
172
|
+
extensions.append(f"altnames: {{{', '.join(altnames_list)}}}")
|
|
173
|
+
|
|
174
|
+
# Units (JSONStructureUnits extension)
|
|
175
|
+
if 'unit' in prop_schema:
|
|
176
|
+
extensions.append(f"unit: {prop_schema['unit']}")
|
|
177
|
+
|
|
178
|
+
# Currency (for decimal types)
|
|
179
|
+
if 'currency' in prop_schema:
|
|
180
|
+
extensions.append(f"currency: {prop_schema['currency']}")
|
|
181
|
+
|
|
182
|
+
# Symbol (from JSONStructureSymbol extension)
|
|
183
|
+
if 'symbol' in prop_schema:
|
|
184
|
+
extensions.append(f"symbol: {prop_schema['symbol']}")
|
|
185
|
+
|
|
186
|
+
# Content encoding/media type (JSONStructureContent extension)
|
|
187
|
+
if 'contentEncoding' in prop_schema:
|
|
188
|
+
extensions.append(f"contentEncoding: {prop_schema['contentEncoding']}")
|
|
189
|
+
if 'contentMediaType' in prop_schema:
|
|
190
|
+
extensions.append(f"contentMediaType: {prop_schema['contentMediaType']}")
|
|
191
|
+
|
|
192
|
+
# Format
|
|
193
|
+
if 'format' in prop_schema:
|
|
194
|
+
extensions.append(f"format: {prop_schema['format']}")
|
|
195
|
+
|
|
196
|
+
# Examples
|
|
197
|
+
if 'examples' in prop_schema:
|
|
198
|
+
examples_str = ', '.join(str(ex) for ex in prop_schema['examples'])
|
|
199
|
+
extensions.append(f"examples: [{examples_str}]")
|
|
200
|
+
|
|
201
|
+
# Default value
|
|
202
|
+
if 'default' in prop_schema:
|
|
203
|
+
extensions.append(f"default: {prop_schema['default']}")
|
|
204
|
+
|
|
205
|
+
if extensions:
|
|
206
|
+
lines.append(f" - Extensions: {', '.join(extensions)}")
|
|
207
|
+
|
|
208
|
+
# Add constraints
|
|
209
|
+
constraints = []
|
|
210
|
+
if 'minLength' in prop_schema:
|
|
211
|
+
constraints.append(f"minLength: {prop_schema['minLength']}")
|
|
212
|
+
if 'maxLength' in prop_schema:
|
|
213
|
+
constraints.append(f"maxLength: {prop_schema['maxLength']}")
|
|
214
|
+
if 'minimum' in prop_schema:
|
|
215
|
+
constraints.append(f"minimum: {prop_schema['minimum']}")
|
|
216
|
+
if 'maximum' in prop_schema:
|
|
217
|
+
constraints.append(f"maximum: {prop_schema['maximum']}")
|
|
218
|
+
if 'exclusiveMinimum' in prop_schema:
|
|
219
|
+
constraints.append(f"exclusiveMinimum: {prop_schema['exclusiveMinimum']}")
|
|
220
|
+
if 'exclusiveMaximum' in prop_schema:
|
|
221
|
+
constraints.append(f"exclusiveMaximum: {prop_schema['exclusiveMaximum']}")
|
|
222
|
+
if 'multipleOf' in prop_schema:
|
|
223
|
+
constraints.append(f"multipleOf: {prop_schema['multipleOf']}")
|
|
224
|
+
if 'pattern' in prop_schema:
|
|
225
|
+
constraints.append(f"pattern: `{prop_schema['pattern']}`")
|
|
226
|
+
if 'minItems' in prop_schema:
|
|
227
|
+
constraints.append(f"minItems: {prop_schema['minItems']}")
|
|
228
|
+
if 'maxItems' in prop_schema:
|
|
229
|
+
constraints.append(f"maxItems: {prop_schema['maxItems']}")
|
|
230
|
+
if 'precision' in prop_schema:
|
|
231
|
+
constraints.append(f"precision: {prop_schema['precision']}")
|
|
232
|
+
if 'scale' in prop_schema:
|
|
233
|
+
constraints.append(f"scale: {prop_schema['scale']}")
|
|
234
|
+
if 'enum' in prop_schema:
|
|
235
|
+
constraints.append(f"enum: {', '.join(str(v) for v in prop_schema['enum'])}")
|
|
236
|
+
if 'const' in prop_schema:
|
|
237
|
+
constraints.append(f"const: {prop_schema['const']}")
|
|
238
|
+
|
|
239
|
+
if constraints:
|
|
240
|
+
lines.append(f" - Constraints: {', '.join(constraints)}")
|
|
241
|
+
|
|
242
|
+
return '\n'.join(lines)
|
|
243
|
+
|
|
244
|
+
def get_type_string(self, schema: Union[Dict, List, str]) -> str:
|
|
245
|
+
"""
|
|
246
|
+
Get a string representation of a type.
|
|
247
|
+
|
|
248
|
+
:param schema: Type schema
|
|
249
|
+
:return: Type string
|
|
250
|
+
"""
|
|
251
|
+
if isinstance(schema, str):
|
|
252
|
+
# Simple type reference or primitive
|
|
253
|
+
if schema.startswith('#/'):
|
|
254
|
+
# Reference
|
|
255
|
+
ref_parts = schema.split('/')
|
|
256
|
+
return f"[{ref_parts[-1]}](#{ref_parts[-1].lower()})"
|
|
257
|
+
return f"`{schema}`"
|
|
258
|
+
|
|
259
|
+
elif isinstance(schema, list):
|
|
260
|
+
# Union type
|
|
261
|
+
type_strs = [self.get_type_string(t) for t in schema]
|
|
262
|
+
return ' | '.join(type_strs)
|
|
263
|
+
|
|
264
|
+
elif isinstance(schema, dict):
|
|
265
|
+
schema_type = schema.get('type')
|
|
266
|
+
|
|
267
|
+
if '$ref' in schema:
|
|
268
|
+
# Reference
|
|
269
|
+
ref = schema['$ref']
|
|
270
|
+
ref_parts = ref.split('/')
|
|
271
|
+
ref_name = ref_parts[-1]
|
|
272
|
+
return f"[{ref_name}](#{ref_name.lower()})"
|
|
273
|
+
|
|
274
|
+
if schema_type == 'array':
|
|
275
|
+
items_type = self.get_type_string(schema.get('items', 'any'))
|
|
276
|
+
return f"array<{items_type}>"
|
|
277
|
+
|
|
278
|
+
elif schema_type == 'set':
|
|
279
|
+
items_type = self.get_type_string(schema.get('items', 'any'))
|
|
280
|
+
return f"set<{items_type}>"
|
|
281
|
+
|
|
282
|
+
elif schema_type == 'map':
|
|
283
|
+
keys_type = self.get_type_string(schema.get('keys', 'string'))
|
|
284
|
+
values_type = self.get_type_string(schema.get('values', 'any'))
|
|
285
|
+
return f"map<{keys_type}, {values_type}>"
|
|
286
|
+
|
|
287
|
+
elif schema_type == 'tuple':
|
|
288
|
+
items = schema.get('items', [])
|
|
289
|
+
if isinstance(items, list):
|
|
290
|
+
item_types = [self.get_type_string(item) for item in items]
|
|
291
|
+
return f"tuple<{', '.join(item_types)}>"
|
|
292
|
+
return "tuple"
|
|
293
|
+
|
|
294
|
+
elif schema_type == 'choice':
|
|
295
|
+
name = schema.get('name', 'Choice')
|
|
296
|
+
return f"[{name}](#{name.lower()})"
|
|
297
|
+
|
|
298
|
+
elif schema_type == 'object':
|
|
299
|
+
name = schema.get('name', 'object')
|
|
300
|
+
if name != 'object':
|
|
301
|
+
return f"[{name}](#{name.lower()})"
|
|
302
|
+
return "`object`"
|
|
303
|
+
|
|
304
|
+
elif schema_type:
|
|
305
|
+
return f"`{schema_type}`"
|
|
306
|
+
|
|
307
|
+
# If no type specified but has properties, it's an inline object
|
|
308
|
+
if 'properties' in schema:
|
|
309
|
+
return "`object` (inline)"
|
|
310
|
+
|
|
311
|
+
return "`any`"
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def convert_structure_to_markdown(structure_schema_path: str, markdown_path: str):
|
|
315
|
+
"""
|
|
316
|
+
Convert a JSON Structure schema file to a Markdown file.
|
|
317
|
+
|
|
318
|
+
:param structure_schema_path: Path to the JSON Structure schema file.
|
|
319
|
+
:param markdown_path: Path to save the Markdown file.
|
|
320
|
+
"""
|
|
321
|
+
converter = StructureToMarkdownConverter(structure_schema_path, markdown_path)
|
|
322
|
+
converter.convert()
|