structurize 3.5.3__tar.gz → 3.5.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. {structurize-3.5.3/structurize.egg-info → structurize-3.5.4}/PKG-INFO +1 -1
  2. {structurize-3.5.3 → structurize-3.5.4}/avrotize/_version.py +3 -3
  3. {structurize-3.5.3 → structurize-3.5.4}/avrotize/kustotojstruct.py +119 -27
  4. {structurize-3.5.3 → structurize-3.5.4/structurize.egg-info}/PKG-INFO +1 -1
  5. {structurize-3.5.3 → structurize-3.5.4}/.gitignore +0 -0
  6. {structurize-3.5.3 → structurize-3.5.4}/LICENSE +0 -0
  7. {structurize-3.5.3 → structurize-3.5.4}/MANIFEST.in +0 -0
  8. {structurize-3.5.3 → structurize-3.5.4}/README.md +0 -0
  9. {structurize-3.5.3 → structurize-3.5.4}/avrotize/__init__.py +0 -0
  10. {structurize-3.5.3 → structurize-3.5.4}/avrotize/__main__.py +0 -0
  11. {structurize-3.5.3 → structurize-3.5.4}/avrotize/asn1toavro.py +0 -0
  12. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotize.py +0 -0
  13. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotocpp.py +0 -0
  14. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotocsharp.py +0 -0
  15. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotocsv.py +0 -0
  16. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotodatapackage.py +0 -0
  17. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotodb.py +0 -0
  18. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotogo.py +0 -0
  19. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotographql.py +0 -0
  20. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotoiceberg.py +0 -0
  21. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotojava.py +0 -0
  22. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotojs.py +0 -0
  23. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotojsons.py +0 -0
  24. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotojstruct.py +0 -0
  25. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotokusto.py +0 -0
  26. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotomd.py +0 -0
  27. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotools.py +0 -0
  28. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotoparquet.py +0 -0
  29. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotoproto.py +0 -0
  30. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotopython.py +0 -0
  31. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotorust.py +0 -0
  32. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotots.py +0 -0
  33. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrotoxsd.py +0 -0
  34. {structurize-3.5.3 → structurize-3.5.4}/avrotize/avrovalidator.py +0 -0
  35. {structurize-3.5.3 → structurize-3.5.4}/avrotize/cddltostructure.py +0 -0
  36. {structurize-3.5.3 → structurize-3.5.4}/avrotize/choice_inference.py +0 -0
  37. {structurize-3.5.3 → structurize-3.5.4}/avrotize/commands.json +0 -0
  38. {structurize-3.5.3 → structurize-3.5.4}/avrotize/common.py +0 -0
  39. {structurize-3.5.3 → structurize-3.5.4}/avrotize/constants.py +0 -0
  40. {structurize-3.5.3 → structurize-3.5.4}/avrotize/csvtoavro.py +0 -0
  41. {structurize-3.5.3 → structurize-3.5.4}/avrotize/datapackagetoavro.py +0 -0
  42. {structurize-3.5.3 → structurize-3.5.4}/avrotize/dependencies/cpp/vcpkg/vcpkg.json +0 -0
  43. {structurize-3.5.3 → structurize-3.5.4}/avrotize/dependencies/typescript/node22/package.json +0 -0
  44. {structurize-3.5.3 → structurize-3.5.4}/avrotize/dependency_resolver.py +0 -0
  45. {structurize-3.5.3 → structurize-3.5.4}/avrotize/dependency_version.py +0 -0
  46. {structurize-3.5.3 → structurize-3.5.4}/avrotize/jsonstoavro.py +0 -0
  47. {structurize-3.5.3 → structurize-3.5.4}/avrotize/jsonstostructure.py +0 -0
  48. {structurize-3.5.3 → structurize-3.5.4}/avrotize/jsontoschema.py +0 -0
  49. {structurize-3.5.3 → structurize-3.5.4}/avrotize/jstructtoavro.py +0 -0
  50. {structurize-3.5.3 → structurize-3.5.4}/avrotize/kstructtoavro.py +0 -0
  51. {structurize-3.5.3 → structurize-3.5.4}/avrotize/kustotoavro.py +0 -0
  52. {structurize-3.5.3 → structurize-3.5.4}/avrotize/mcp_server.py +0 -0
  53. {structurize-3.5.3 → structurize-3.5.4}/avrotize/openapitostructure.py +0 -0
  54. {structurize-3.5.3 → structurize-3.5.4}/avrotize/parquettoavro.py +0 -0
  55. {structurize-3.5.3 → structurize-3.5.4}/avrotize/proto2parser.py +0 -0
  56. {structurize-3.5.3 → structurize-3.5.4}/avrotize/proto3parser.py +0 -0
  57. {structurize-3.5.3 → structurize-3.5.4}/avrotize/prototoavro.py +0 -0
  58. {structurize-3.5.3 → structurize-3.5.4}/avrotize/schema_inference.py +0 -0
  59. {structurize-3.5.3 → structurize-3.5.4}/avrotize/sqltoavro.py +0 -0
  60. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretocddl.py +0 -0
  61. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretocpp.py +0 -0
  62. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretocsharp.py +0 -0
  63. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretocsv.py +0 -0
  64. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretodatapackage.py +0 -0
  65. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretodb.py +0 -0
  66. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretogo.py +0 -0
  67. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretographql.py +0 -0
  68. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretoiceberg.py +0 -0
  69. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretojava.py +0 -0
  70. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretojs.py +0 -0
  71. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretojsons.py +0 -0
  72. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretokusto.py +0 -0
  73. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretomd.py +0 -0
  74. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretoproto.py +0 -0
  75. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretopython.py +0 -0
  76. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretorust.py +0 -0
  77. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretots.py +0 -0
  78. {structurize-3.5.3 → structurize-3.5.4}/avrotize/structuretoxsd.py +0 -0
  79. {structurize-3.5.3 → structurize-3.5.4}/avrotize/validate.py +0 -0
  80. {structurize-3.5.3 → structurize-3.5.4}/avrotize/xmltoschema.py +0 -0
  81. {structurize-3.5.3 → structurize-3.5.4}/avrotize/xsdtoavro.py +0 -0
  82. {structurize-3.5.3 → structurize-3.5.4}/build.ps1 +0 -0
  83. {structurize-3.5.3 → structurize-3.5.4}/build.sh +0 -0
  84. {structurize-3.5.3 → structurize-3.5.4}/pyproject.toml +0 -0
  85. {structurize-3.5.3 → structurize-3.5.4}/setup.cfg +0 -0
  86. {structurize-3.5.3 → structurize-3.5.4}/structurize.egg-info/SOURCES.txt +0 -0
  87. {structurize-3.5.3 → structurize-3.5.4}/structurize.egg-info/dependency_links.txt +0 -0
  88. {structurize-3.5.3 → structurize-3.5.4}/structurize.egg-info/entry_points.txt +0 -0
  89. {structurize-3.5.3 → structurize-3.5.4}/structurize.egg-info/requires.txt +0 -0
  90. {structurize-3.5.3 → structurize-3.5.4}/structurize.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: structurize
3
- Version: 3.5.3
3
+ Version: 3.5.4
4
4
  Summary: Tools to convert from and to JSON Structure from various other schema languages.
5
5
  Author-email: Clemens Vasters <clemensv@microsoft.com>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '3.5.3'
22
- __version_tuple__ = version_tuple = (3, 5, 3)
21
+ __version__ = version = '3.5.4'
22
+ __version_tuple__ = version_tuple = (3, 5, 4)
23
23
 
24
- __commit_id__ = commit_id = 'g4c9a891f7'
24
+ __commit_id__ = commit_id = 'g783dbb9df'
@@ -85,7 +85,11 @@ class KustoToJsonStructure:
85
85
  return self.type_map.get(kusto_type, "string")
86
86
 
87
87
  def kusto_to_jstruct_schema(self, kusto_schema: dict, table_name: str) -> JsonNode:
88
- """ Converts a Kusto schema to JSON Structure schema."""
88
+ """ Converts a Kusto schema to JSON Structure schema.
89
+
90
+ Returns a list of tuples (type_value, schema) where type_value is the CloudEvents
91
+ type value (or None for non-CloudEvents tables).
92
+ """
89
93
  column_names = set([column['Name'].lstrip('_')
90
94
  for column in kusto_schema['OrderedColumns']])
91
95
  type_values: List[str|None] = []
@@ -105,7 +109,7 @@ class KustoToJsonStructure:
105
109
  if len(type_values) == 0:
106
110
  type_values.append(None)
107
111
 
108
- schemas: List[JsonNode] = []
112
+ schemas: List[tuple] = []
109
113
  for type_value in type_values:
110
114
  schema: JsonNode = {}
111
115
  properties: Dict[str, JsonNode] = {}
@@ -120,10 +124,11 @@ class KustoToJsonStructure:
120
124
  data_schemas = [data_schemas]
121
125
  if isinstance(data_schemas, list):
122
126
  for schema in data_schemas:
123
- if not isinstance(schema, dict) or "type" not in schema or schema["type"] != "object":
124
- schema = self.wrap_schema_in_root_record(schema, type_name)
127
+ if isinstance(schema, dict):
128
+ # Remove inferrer artifacts that don't belong in the final schema
129
+ schema.pop("root", None)
125
130
  self.apply_schema_attributes(schema, kusto_schema, table_name, type_value)
126
- schemas.append(schema)
131
+ schemas.append((type_value, schema))
127
132
  else:
128
133
  for column in kusto_schema['OrderedColumns']:
129
134
  jstruct_type = self.map_kusto_type_to_jstruct_type(
@@ -147,9 +152,9 @@ class KustoToJsonStructure:
147
152
  "properties": properties
148
153
  }
149
154
  self.apply_schema_attributes(schema, kusto_schema, table_name, type_value)
150
- schemas.append(schema)
155
+ schemas.append((type_value, schema))
151
156
 
152
- return schemas if len(schemas) > 1 else schemas[0]
157
+ return schemas
153
158
 
154
159
 
155
160
  def wrap_schema_in_root_record(self, schema: JsonNode, type_name: str):
@@ -188,6 +193,16 @@ class KustoToJsonStructure:
188
193
  table_names = [row['TableName'] for row in rows.primary_results[0]]
189
194
  return table_names
190
195
 
196
+ def _derive_schema_id(self, type_value: str | None, table_name: str) -> str:
197
+ """Derives a schema ID from the event type value or table name."""
198
+ if type_value:
199
+ return type_value
200
+ return table_name
201
+
202
+ def _derive_group_id(self, table_name: str) -> str:
203
+ """Derives a message group ID from the table name."""
204
+ return table_name
205
+
191
206
  def process_all_tables(self):
192
207
  """ Processes all tables in the Kusto database."""
193
208
  if self.single_table_name:
@@ -195,15 +210,13 @@ class KustoToJsonStructure:
195
210
  else:
196
211
  table_names = self.fetch_all_table_names()
197
212
 
198
- all_schemas = []
213
+ # Collect all (type_value, schema) tuples grouped by table
214
+ all_entries: List[tuple] = []
199
215
  for table_name in table_names:
200
216
  kusto_schema = self.fetch_table_schema_and_docs(table_name)
201
- jstruct_schema = self.kusto_to_jstruct_schema(kusto_schema, table_name)
202
-
203
- if isinstance(jstruct_schema, list):
204
- all_schemas.extend(jstruct_schema)
205
- else:
206
- all_schemas.append(jstruct_schema)
217
+ entries = self.kusto_to_jstruct_schema(kusto_schema, table_name)
218
+ for entry in entries:
219
+ all_entries.append((table_name, entry[0], entry[1]))
207
220
 
208
221
  # Write output
209
222
  output_dir = os.path.dirname(self.jstruct_schema_path)
@@ -211,26 +224,105 @@ class KustoToJsonStructure:
211
224
  os.makedirs(output_dir)
212
225
 
213
226
  if self.emit_xregistry:
214
- # Create xRegistry manifest
215
- output = {
216
- "$schema": "https://cloudevents.io/schemas/registry",
217
- "specversion": "0.5-wip",
218
- "endpoints": {},
219
- "messagegroups": {},
220
- "schemagroups": {
221
- f"{self.kusto_database}": {
222
- "schemas": {schema.get("$id", f"schema_{i}"): {"format": "JSONStructure/1.0", "schema": schema}
223
- for i, schema in enumerate(all_schemas)}
224
- }
225
- }
226
- }
227
+ output = self._build_xregistry_manifest(all_entries)
227
228
  else:
228
229
  # Single schema or array of schemas
230
+ all_schemas = [entry[2] for entry in all_entries]
229
231
  output = all_schemas if len(all_schemas) > 1 else all_schemas[0] if all_schemas else {}
230
232
 
231
233
  with open(self.jstruct_schema_path, 'w', encoding='utf-8') as jstruct_file:
232
234
  json.dump(output, jstruct_file, indent=4)
233
235
 
236
+ def _build_xregistry_manifest(self, all_entries: List[tuple]) -> dict:
237
+ """Builds an xRegistry manifest with messagegroups and schemagroups.
238
+
239
+ Args:
240
+ all_entries: List of (table_name, type_value, schema) tuples.
241
+ """
242
+ messagegroups: Dict[str, JsonNode] = {}
243
+ schemagroups: Dict[str, JsonNode] = {}
244
+
245
+ # Group entries by table
246
+ tables: Dict[str, List[tuple]] = {}
247
+ for table_name, type_value, schema in all_entries:
248
+ if table_name not in tables:
249
+ tables[table_name] = []
250
+ tables[table_name].append((type_value, schema))
251
+
252
+ for table_name, entries in tables.items():
253
+ group_id = self._derive_group_id(table_name)
254
+ has_cloudevents = any(tv is not None for tv, _ in entries)
255
+
256
+ # Build schema group
257
+ schemas: Dict[str, JsonNode] = {}
258
+ for type_value, schema in entries:
259
+ schema_id = self._derive_schema_id(type_value, table_name)
260
+ schemas[schema_id] = {
261
+ "format": "JSONStructure/1.0",
262
+ "versions": {
263
+ "1": {
264
+ "format": "JSONStructure/1.0",
265
+ "schema": schema
266
+ }
267
+ }
268
+ }
269
+ schemagroups[group_id] = {"schemas": schemas}
270
+
271
+ if has_cloudevents:
272
+ # Build message group with CloudEvents messages
273
+ messages: Dict[str, JsonNode] = {}
274
+ for type_value, schema in entries:
275
+ if type_value is None:
276
+ continue
277
+ schema_id = self._derive_schema_id(type_value, table_name)
278
+ messages[type_value] = {
279
+ "description": f"CloudEvent of type {type_value}",
280
+ "envelope": "CloudEvents/1.0",
281
+ "envelopemetadata": {
282
+ "id": {
283
+ "required": True
284
+ },
285
+ "type": {
286
+ "value": type_value
287
+ },
288
+ "source": {
289
+ "required": True
290
+ },
291
+ "time": {
292
+ "required": True
293
+ }
294
+ },
295
+ "datacontenttype": "application/json",
296
+ "dataschemaformat": "JSONStructure/1.0",
297
+ "dataschemauri": f"#/schemagroups/{group_id}/schemas/{schema_id}"
298
+ }
299
+ messagegroups[group_id] = {
300
+ "envelope": "CloudEvents/1.0",
301
+ "description": f"Events from {table_name}",
302
+ "messages": messages
303
+ }
304
+ else:
305
+ # Non-CloudEvents table: add a simple message group entry
306
+ messages = {}
307
+ for type_value, schema in entries:
308
+ schema_id = self._derive_schema_id(type_value, table_name)
309
+ messages[schema_id] = {
310
+ "description": f"Message from {table_name}",
311
+ "dataschemaformat": "JSONStructure/1.0",
312
+ "dataschemauri": f"#/schemagroups/{group_id}/schemas/{schema_id}"
313
+ }
314
+ messagegroups[group_id] = {
315
+ "description": f"Messages from {table_name}",
316
+ "messages": messages
317
+ }
318
+
319
+ return {
320
+ "$schema": "https://cloudevents.io/schemas/registry",
321
+ "specversion": "0.5-wip",
322
+ "messagegroups": messagegroups,
323
+ "schemagroups": schemagroups
324
+ }
325
+
234
326
 
235
327
  def convert_kusto_to_jstruct(kusto_uri: str, kusto_database: str, table_name: str | None, base_id: str, jstruct_schema_file: str, emit_cloudevents: bool, emit_cloudevents_xregistry: bool, token_provider=None, sample_size: int = 100, infer_choices: bool = False, choice_depth: int = 1, infer_enums: bool = False):
236
328
  """ Converts Kusto table schemas to JSON Structure schema format."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: structurize
3
- Version: 3.5.3
3
+ Version: 3.5.4
4
4
  Summary: Tools to convert from and to JSON Structure from various other schema languages.
5
5
  Author-email: Clemens Vasters <clemensv@microsoft.com>
6
6
  Classifier: Programming Language :: Python :: 3
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes