structurize 2.16.2__py3-none-any.whl → 2.16.6__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 (54) hide show
  1. avrotize/__init__.py +63 -63
  2. avrotize/__main__.py +5 -5
  3. avrotize/_version.py +34 -34
  4. avrotize/asn1toavro.py +160 -160
  5. avrotize/avrotize.py +152 -152
  6. avrotize/avrotocpp.py +483 -483
  7. avrotize/avrotocsharp.py +992 -992
  8. avrotize/avrotocsv.py +121 -121
  9. avrotize/avrotodatapackage.py +173 -173
  10. avrotize/avrotodb.py +1383 -1383
  11. avrotize/avrotogo.py +476 -476
  12. avrotize/avrotographql.py +197 -197
  13. avrotize/avrotoiceberg.py +210 -210
  14. avrotize/avrotojava.py +1023 -1023
  15. avrotize/avrotojs.py +250 -250
  16. avrotize/avrotojsons.py +481 -481
  17. avrotize/avrotojstruct.py +345 -345
  18. avrotize/avrotokusto.py +363 -363
  19. avrotize/avrotomd.py +137 -137
  20. avrotize/avrotools.py +168 -168
  21. avrotize/avrotoparquet.py +208 -208
  22. avrotize/avrotoproto.py +358 -358
  23. avrotize/avrotopython.py +622 -622
  24. avrotize/avrotorust.py +435 -435
  25. avrotize/avrotots.py +598 -598
  26. avrotize/avrotoxsd.py +344 -344
  27. avrotize/commands.json +2493 -2433
  28. avrotize/common.py +828 -828
  29. avrotize/constants.py +4 -4
  30. avrotize/csvtoavro.py +131 -131
  31. avrotize/datapackagetoavro.py +76 -76
  32. avrotize/dependency_resolver.py +348 -348
  33. avrotize/jsonstoavro.py +1698 -1698
  34. avrotize/jsonstostructure.py +2642 -2642
  35. avrotize/jstructtoavro.py +878 -878
  36. avrotize/kstructtoavro.py +93 -93
  37. avrotize/kustotoavro.py +455 -455
  38. avrotize/parquettoavro.py +157 -157
  39. avrotize/proto2parser.py +497 -497
  40. avrotize/proto3parser.py +402 -402
  41. avrotize/prototoavro.py +382 -382
  42. avrotize/structuretocsharp.py +2005 -2005
  43. avrotize/structuretojsons.py +498 -498
  44. avrotize/structuretopython.py +772 -772
  45. avrotize/structuretots.py +653 -0
  46. avrotize/xsdtoavro.py +413 -413
  47. structurize-2.16.6.dist-info/METADATA +107 -0
  48. structurize-2.16.6.dist-info/RECORD +52 -0
  49. {structurize-2.16.2.dist-info → structurize-2.16.6.dist-info}/licenses/LICENSE +200 -200
  50. structurize-2.16.2.dist-info/METADATA +0 -805
  51. structurize-2.16.2.dist-info/RECORD +0 -51
  52. {structurize-2.16.2.dist-info → structurize-2.16.6.dist-info}/WHEEL +0 -0
  53. {structurize-2.16.2.dist-info → structurize-2.16.6.dist-info}/entry_points.txt +0 -0
  54. {structurize-2.16.2.dist-info → structurize-2.16.6.dist-info}/top_level.txt +0 -0
avrotize/avrotocsv.py CHANGED
@@ -1,121 +1,121 @@
1
- # coding: utf-8
2
- """
3
- Module to convert Avro schema to CSV schema.
4
- """
5
-
6
- import json
7
- import os
8
-
9
- class AvroToCSVSchemaConverter:
10
- """
11
- Class to convert Avro schema to CSV schema.
12
- """
13
-
14
- def __init__(self, avro_schema_path, csv_schema_path):
15
- """
16
- Initialize the converter with file paths.
17
-
18
- :param avro_schema_path: Path to the Avro schema file.
19
- :param csv_schema_path: Path to save the CSV schema file.
20
- """
21
- self.avro_schema_path = avro_schema_path
22
- self.csv_schema_path = csv_schema_path
23
-
24
- def convert(self):
25
- """
26
- Convert Avro schema to CSV schema and save to file.
27
- """
28
- with open(self.avro_schema_path, 'r', encoding='utf-8') as file:
29
- avro_schema = json.load(file)
30
-
31
- csv_schema = self.convert_avro_to_csv_schema(avro_schema)
32
-
33
- with open(self.csv_schema_path, 'w', encoding='utf-8') as file:
34
- json.dump(csv_schema, file, indent=2)
35
-
36
- def convert_avro_to_csv_schema(self, avro_schema):
37
- """
38
- Convert an Avro schema to a CSV schema.
39
-
40
- :param avro_schema: Avro schema as a dictionary.
41
- :return: CSV schema as a dictionary.
42
- """
43
- csv_schema = {
44
- "fields": []
45
- }
46
-
47
- for field in avro_schema['fields']:
48
- csv_field = self.convert_avro_field_to_csv_field(field)
49
- csv_schema['fields'].append(csv_field)
50
-
51
- return csv_schema
52
-
53
- def convert_avro_field_to_csv_field(self, field):
54
- """
55
- Convert an Avro field to a CSV field.
56
-
57
- :param field: Avro field as a dictionary.
58
- :return: CSV field as a dictionary.
59
- """
60
- csv_field = {
61
- "name": field['name'],
62
- "type": self.convert_avro_type_to_csv_type(field['type'])
63
- }
64
-
65
- if isinstance(field['type'], dict) and field['type'].get('logicalType') == 'timestamp-millis':
66
- csv_field['type'] = 'string'
67
- csv_field['format'] = 'datetime'
68
-
69
- if field.get('default') is not None:
70
- csv_field['default'] = field['default']
71
-
72
- if isinstance(field['type'], list) and "null" in field['type']:
73
- csv_field['nullable'] = True
74
-
75
- if 'enum' in field['type']:
76
- csv_field['enum'] = field['type']['symbols']
77
-
78
- return csv_field
79
-
80
- def convert_avro_type_to_csv_type(self, avro_type):
81
- """
82
- Convert an Avro type to a CSV type.
83
-
84
- :param avro_type: Avro type as a string or dictionary.
85
- :return: CSV type as a string.
86
- """
87
- if isinstance(avro_type, list):
88
- avro_type = [t for t in avro_type if t != "null"][0]
89
-
90
- type_mapping = {
91
- "string": "string",
92
- "int": "integer",
93
- "long": "integer",
94
- "float": "number",
95
- "double": "number",
96
- "boolean": "boolean",
97
- "bytes": "string",
98
- "record": "object",
99
- "array": "array",
100
- "map": "object",
101
- "enum": "string"
102
- }
103
-
104
- if isinstance(avro_type, dict):
105
- return type_mapping.get(avro_type['type'], "string")
106
-
107
- return type_mapping.get(avro_type, "string")
108
-
109
- def convert_avro_to_csv_schema(avro_schema_path, csv_schema_path):
110
- """
111
- Convert an Avro schema file to a CSV schema file.
112
-
113
- :param avro_schema_path: Path to the Avro schema file.
114
- :param csv_schema_path: Path to save the CSV schema file.
115
- """
116
-
117
- if not os.path.exists(avro_schema_path):
118
- raise FileNotFoundError(f"Avro schema file not found: {avro_schema_path}")
119
-
120
- converter = AvroToCSVSchemaConverter(avro_schema_path, csv_schema_path)
121
- converter.convert()
1
+ # coding: utf-8
2
+ """
3
+ Module to convert Avro schema to CSV schema.
4
+ """
5
+
6
+ import json
7
+ import os
8
+
9
+ class AvroToCSVSchemaConverter:
10
+ """
11
+ Class to convert Avro schema to CSV schema.
12
+ """
13
+
14
+ def __init__(self, avro_schema_path, csv_schema_path):
15
+ """
16
+ Initialize the converter with file paths.
17
+
18
+ :param avro_schema_path: Path to the Avro schema file.
19
+ :param csv_schema_path: Path to save the CSV schema file.
20
+ """
21
+ self.avro_schema_path = avro_schema_path
22
+ self.csv_schema_path = csv_schema_path
23
+
24
+ def convert(self):
25
+ """
26
+ Convert Avro schema to CSV schema and save to file.
27
+ """
28
+ with open(self.avro_schema_path, 'r', encoding='utf-8') as file:
29
+ avro_schema = json.load(file)
30
+
31
+ csv_schema = self.convert_avro_to_csv_schema(avro_schema)
32
+
33
+ with open(self.csv_schema_path, 'w', encoding='utf-8') as file:
34
+ json.dump(csv_schema, file, indent=2)
35
+
36
+ def convert_avro_to_csv_schema(self, avro_schema):
37
+ """
38
+ Convert an Avro schema to a CSV schema.
39
+
40
+ :param avro_schema: Avro schema as a dictionary.
41
+ :return: CSV schema as a dictionary.
42
+ """
43
+ csv_schema = {
44
+ "fields": []
45
+ }
46
+
47
+ for field in avro_schema['fields']:
48
+ csv_field = self.convert_avro_field_to_csv_field(field)
49
+ csv_schema['fields'].append(csv_field)
50
+
51
+ return csv_schema
52
+
53
+ def convert_avro_field_to_csv_field(self, field):
54
+ """
55
+ Convert an Avro field to a CSV field.
56
+
57
+ :param field: Avro field as a dictionary.
58
+ :return: CSV field as a dictionary.
59
+ """
60
+ csv_field = {
61
+ "name": field['name'],
62
+ "type": self.convert_avro_type_to_csv_type(field['type'])
63
+ }
64
+
65
+ if isinstance(field['type'], dict) and field['type'].get('logicalType') == 'timestamp-millis':
66
+ csv_field['type'] = 'string'
67
+ csv_field['format'] = 'datetime'
68
+
69
+ if field.get('default') is not None:
70
+ csv_field['default'] = field['default']
71
+
72
+ if isinstance(field['type'], list) and "null" in field['type']:
73
+ csv_field['nullable'] = True
74
+
75
+ if 'enum' in field['type']:
76
+ csv_field['enum'] = field['type']['symbols']
77
+
78
+ return csv_field
79
+
80
+ def convert_avro_type_to_csv_type(self, avro_type):
81
+ """
82
+ Convert an Avro type to a CSV type.
83
+
84
+ :param avro_type: Avro type as a string or dictionary.
85
+ :return: CSV type as a string.
86
+ """
87
+ if isinstance(avro_type, list):
88
+ avro_type = [t for t in avro_type if t != "null"][0]
89
+
90
+ type_mapping = {
91
+ "string": "string",
92
+ "int": "integer",
93
+ "long": "integer",
94
+ "float": "number",
95
+ "double": "number",
96
+ "boolean": "boolean",
97
+ "bytes": "string",
98
+ "record": "object",
99
+ "array": "array",
100
+ "map": "object",
101
+ "enum": "string"
102
+ }
103
+
104
+ if isinstance(avro_type, dict):
105
+ return type_mapping.get(avro_type['type'], "string")
106
+
107
+ return type_mapping.get(avro_type, "string")
108
+
109
+ def convert_avro_to_csv_schema(avro_schema_path, csv_schema_path):
110
+ """
111
+ Convert an Avro schema file to a CSV schema file.
112
+
113
+ :param avro_schema_path: Path to the Avro schema file.
114
+ :param csv_schema_path: Path to save the CSV schema file.
115
+ """
116
+
117
+ if not os.path.exists(avro_schema_path):
118
+ raise FileNotFoundError(f"Avro schema file not found: {avro_schema_path}")
119
+
120
+ converter = AvroToCSVSchemaConverter(avro_schema_path, csv_schema_path)
121
+ converter.convert()
@@ -1,173 +1,173 @@
1
- import json
2
- import sys
3
- from typing import Dict, List, cast, Optional
4
- from datapackage import Package, Resource
5
-
6
- from avrotize.common import get_longest_namespace_prefix
7
-
8
-
9
- JsonNode = Dict[str, 'JsonNode'] | List['JsonNode'] | str | bool | int | None
10
-
11
- class AvroToDataPackageConverter:
12
- """Class to convert Avro schema to Data Package."""
13
-
14
- def __init__(self: 'AvroToDataPackageConverter'):
15
- self.named_type_cache: Dict[str, JsonNode] = {}
16
-
17
- def get_fullname(self, namespace: str, name: str) -> str:
18
- """Get the full name of a record type."""
19
- return f"{namespace}.{name}" if namespace else name
20
-
21
- def convert_avro_to_datapackage(self, avro_schema_path: str, avro_record_type: Optional[str], datapackage_path: str):
22
- """Convert an Avro schema to a Data Package."""
23
- with open(avro_schema_path, "r", encoding="utf-8") as f:
24
- schema_json = f.read()
25
-
26
- # Parse the schema as a JSON object
27
- schema = json.loads(schema_json)
28
- self.cache_named_types(schema)
29
-
30
- if isinstance(schema, list):
31
- if avro_record_type:
32
- schema = next(
33
- (x for x in schema if x["name"] == avro_record_type or x["namespace"] + "." + x["name"] == avro_record_type), None)
34
- if schema is None:
35
- print(f"No top-level record type {avro_record_type} found in the Avro schema")
36
- sys.exit(1)
37
- schemas_to_convert = schema
38
- elif isinstance(schema, dict):
39
- schemas_to_convert = [schema]
40
- else:
41
- print("Expected a single Avro schema as a JSON object, or a list of schema records")
42
- sys.exit(1)
43
-
44
- longest_namespace_prefix = get_longest_namespace_prefix(schema)
45
- self.create_datapackage_for_schemas(schemas_to_convert, datapackage_path, longest_namespace_prefix)
46
-
47
- def create_datapackage_for_schemas(self, schemas: List[Dict[str, JsonNode]], datapackage_path: str, namespace_prefix: str):
48
- """Create a Data Package for given schemas."""
49
- package = Package()
50
- data_package_resources = []
51
-
52
- for schema in schemas:
53
- name = str(schema["name"])
54
- namespace = str(schema.get("namespace", ""))
55
- if namespace.startswith(namespace_prefix):
56
- namespace = namespace[len(namespace_prefix):].strip(".")
57
- table_name = f"{namespace}_{name}" if namespace else name
58
- fields = cast(List[Dict[str, JsonNode]], schema["fields"])
59
-
60
- # Create the Data Package schema
61
- resource_schema: Dict[str, List[JsonNode]] = {
62
- "fields": []
63
- }
64
-
65
- for field in fields:
66
- column_name = field["name"]
67
- column_type = self.convert_avro_type_to_datapackage_type(field["type"])
68
- field_schema = {"name": column_name, "type": column_type}
69
- if "doc" in field:
70
- field_schema["description"] = field["doc"]
71
- resource_schema["fields"].append(field_schema)
72
-
73
- resource = {
74
- "name": table_name,
75
- "schema": resource_schema
76
- }
77
- data_package_resources.append(resource)
78
-
79
- # Add resources to the Data Package
80
- for resource in data_package_resources:
81
- package.add_resource(resource)
82
-
83
- # Save the Data Package
84
- package.descriptor["name"] = namespace_prefix
85
- package.commit()
86
-
87
- with open(datapackage_path, "w", encoding="utf-8") as f:
88
- f.write(json.dumps(package.descriptor, indent=2))
89
-
90
- def convert_avro_type_to_datapackage_type(self, avro_type: JsonNode) -> str:
91
- """Convert an Avro type to a Data Package type."""
92
- if isinstance(avro_type, list):
93
- item_count = len(avro_type)
94
- if item_count == 1:
95
- return self.convert_avro_type_to_datapackage_type(avro_type[0])
96
- elif item_count == 2:
97
- first = avro_type[0]
98
- second = avro_type[1]
99
- if isinstance(first, str) and first == "null":
100
- return self.convert_avro_type_to_datapackage_type(second)
101
- elif isinstance(second, str) and second == "null":
102
- return self.convert_avro_type_to_datapackage_type(first)
103
- print(f"WARNING: Complex union types are not fully supported: {avro_type}")
104
- return "string"
105
- elif isinstance(avro_type, dict):
106
- type_name = avro_type.get("type")
107
- if type_name == "array":
108
- return "array"
109
- elif type_name == "map":
110
- return "object"
111
- elif type_name == "record":
112
- return "object"
113
- elif type_name == "enum":
114
- return "string"
115
- elif type_name == "fixed":
116
- return "string"
117
- elif type_name == "string":
118
- return "string"
119
- elif type_name == "bytes":
120
- return "string"
121
- elif type_name == "long":
122
- return "integer"
123
- elif type_name == "int":
124
- return "integer"
125
- elif type_name == "float":
126
- return "number"
127
- elif type_name == "double":
128
- return "number"
129
- elif type_name == "boolean":
130
- return "boolean"
131
- else:
132
- return "string"
133
- elif isinstance(avro_type, str):
134
- if avro_type in self.named_type_cache:
135
- return self.convert_avro_type_to_datapackage_type(self.named_type_cache[avro_type])
136
- return self.map_scalar_type(avro_type)
137
-
138
- return "string"
139
-
140
- def cache_named_types(self, avro_type: JsonNode):
141
- """Add an encountered type to the list of types."""
142
- if isinstance(avro_type, list):
143
- for item in avro_type:
144
- self.cache_named_types(item)
145
- if isinstance(avro_type, dict) and avro_type.get("name"):
146
- self.named_type_cache[self.get_fullname(str(avro_type.get(
147
- "namespace")), str(avro_type.get("name")))] = avro_type
148
- if "fields" in avro_type:
149
- for field in cast(List[Dict[str,JsonNode]],avro_type.get("fields")):
150
- if "type" in field:
151
- self.cache_named_types(field.get("type"))
152
-
153
- def map_scalar_type(self, type_name: str) -> str:
154
- """Map an Avro scalar type to a Data Package scalar type."""
155
- scalar_type_mapping = {
156
- "null": "string",
157
- "int": "integer",
158
- "long": "integer",
159
- "float": "number",
160
- "double": "number",
161
- "boolean": "boolean",
162
- "bytes": "string",
163
- "string": "string"
164
- }
165
- return scalar_type_mapping.get(type_name, "string")
166
-
167
- def convert_avro_to_datapackage(avro_schema_path: str, avro_record_type: Optional[str], datapackage_path: str):
168
- """Convert an Avro schema to a Data Package."""
169
- converter = AvroToDataPackageConverter()
170
- converter.convert_avro_to_datapackage(avro_schema_path, avro_record_type, datapackage_path)
171
-
172
- # Example usage:
173
- # convert_avro_to_datapackage("schema.avsc", "MyRecord", "datapackage.json")
1
+ import json
2
+ import sys
3
+ from typing import Dict, List, cast, Optional
4
+ from datapackage import Package, Resource
5
+
6
+ from avrotize.common import get_longest_namespace_prefix
7
+
8
+
9
+ JsonNode = Dict[str, 'JsonNode'] | List['JsonNode'] | str | bool | int | None
10
+
11
+ class AvroToDataPackageConverter:
12
+ """Class to convert Avro schema to Data Package."""
13
+
14
+ def __init__(self: 'AvroToDataPackageConverter'):
15
+ self.named_type_cache: Dict[str, JsonNode] = {}
16
+
17
+ def get_fullname(self, namespace: str, name: str) -> str:
18
+ """Get the full name of a record type."""
19
+ return f"{namespace}.{name}" if namespace else name
20
+
21
+ def convert_avro_to_datapackage(self, avro_schema_path: str, avro_record_type: Optional[str], datapackage_path: str):
22
+ """Convert an Avro schema to a Data Package."""
23
+ with open(avro_schema_path, "r", encoding="utf-8") as f:
24
+ schema_json = f.read()
25
+
26
+ # Parse the schema as a JSON object
27
+ schema = json.loads(schema_json)
28
+ self.cache_named_types(schema)
29
+
30
+ if isinstance(schema, list):
31
+ if avro_record_type:
32
+ schema = next(
33
+ (x for x in schema if x["name"] == avro_record_type or x["namespace"] + "." + x["name"] == avro_record_type), None)
34
+ if schema is None:
35
+ print(f"No top-level record type {avro_record_type} found in the Avro schema")
36
+ sys.exit(1)
37
+ schemas_to_convert = schema
38
+ elif isinstance(schema, dict):
39
+ schemas_to_convert = [schema]
40
+ else:
41
+ print("Expected a single Avro schema as a JSON object, or a list of schema records")
42
+ sys.exit(1)
43
+
44
+ longest_namespace_prefix = get_longest_namespace_prefix(schema)
45
+ self.create_datapackage_for_schemas(schemas_to_convert, datapackage_path, longest_namespace_prefix)
46
+
47
+ def create_datapackage_for_schemas(self, schemas: List[Dict[str, JsonNode]], datapackage_path: str, namespace_prefix: str):
48
+ """Create a Data Package for given schemas."""
49
+ package = Package()
50
+ data_package_resources = []
51
+
52
+ for schema in schemas:
53
+ name = str(schema["name"])
54
+ namespace = str(schema.get("namespace", ""))
55
+ if namespace.startswith(namespace_prefix):
56
+ namespace = namespace[len(namespace_prefix):].strip(".")
57
+ table_name = f"{namespace}_{name}" if namespace else name
58
+ fields = cast(List[Dict[str, JsonNode]], schema["fields"])
59
+
60
+ # Create the Data Package schema
61
+ resource_schema: Dict[str, List[JsonNode]] = {
62
+ "fields": []
63
+ }
64
+
65
+ for field in fields:
66
+ column_name = field["name"]
67
+ column_type = self.convert_avro_type_to_datapackage_type(field["type"])
68
+ field_schema = {"name": column_name, "type": column_type}
69
+ if "doc" in field:
70
+ field_schema["description"] = field["doc"]
71
+ resource_schema["fields"].append(field_schema)
72
+
73
+ resource = {
74
+ "name": table_name,
75
+ "schema": resource_schema
76
+ }
77
+ data_package_resources.append(resource)
78
+
79
+ # Add resources to the Data Package
80
+ for resource in data_package_resources:
81
+ package.add_resource(resource)
82
+
83
+ # Save the Data Package
84
+ package.descriptor["name"] = namespace_prefix
85
+ package.commit()
86
+
87
+ with open(datapackage_path, "w", encoding="utf-8") as f:
88
+ f.write(json.dumps(package.descriptor, indent=2))
89
+
90
+ def convert_avro_type_to_datapackage_type(self, avro_type: JsonNode) -> str:
91
+ """Convert an Avro type to a Data Package type."""
92
+ if isinstance(avro_type, list):
93
+ item_count = len(avro_type)
94
+ if item_count == 1:
95
+ return self.convert_avro_type_to_datapackage_type(avro_type[0])
96
+ elif item_count == 2:
97
+ first = avro_type[0]
98
+ second = avro_type[1]
99
+ if isinstance(first, str) and first == "null":
100
+ return self.convert_avro_type_to_datapackage_type(second)
101
+ elif isinstance(second, str) and second == "null":
102
+ return self.convert_avro_type_to_datapackage_type(first)
103
+ print(f"WARNING: Complex union types are not fully supported: {avro_type}")
104
+ return "string"
105
+ elif isinstance(avro_type, dict):
106
+ type_name = avro_type.get("type")
107
+ if type_name == "array":
108
+ return "array"
109
+ elif type_name == "map":
110
+ return "object"
111
+ elif type_name == "record":
112
+ return "object"
113
+ elif type_name == "enum":
114
+ return "string"
115
+ elif type_name == "fixed":
116
+ return "string"
117
+ elif type_name == "string":
118
+ return "string"
119
+ elif type_name == "bytes":
120
+ return "string"
121
+ elif type_name == "long":
122
+ return "integer"
123
+ elif type_name == "int":
124
+ return "integer"
125
+ elif type_name == "float":
126
+ return "number"
127
+ elif type_name == "double":
128
+ return "number"
129
+ elif type_name == "boolean":
130
+ return "boolean"
131
+ else:
132
+ return "string"
133
+ elif isinstance(avro_type, str):
134
+ if avro_type in self.named_type_cache:
135
+ return self.convert_avro_type_to_datapackage_type(self.named_type_cache[avro_type])
136
+ return self.map_scalar_type(avro_type)
137
+
138
+ return "string"
139
+
140
+ def cache_named_types(self, avro_type: JsonNode):
141
+ """Add an encountered type to the list of types."""
142
+ if isinstance(avro_type, list):
143
+ for item in avro_type:
144
+ self.cache_named_types(item)
145
+ if isinstance(avro_type, dict) and avro_type.get("name"):
146
+ self.named_type_cache[self.get_fullname(str(avro_type.get(
147
+ "namespace")), str(avro_type.get("name")))] = avro_type
148
+ if "fields" in avro_type:
149
+ for field in cast(List[Dict[str,JsonNode]],avro_type.get("fields")):
150
+ if "type" in field:
151
+ self.cache_named_types(field.get("type"))
152
+
153
+ def map_scalar_type(self, type_name: str) -> str:
154
+ """Map an Avro scalar type to a Data Package scalar type."""
155
+ scalar_type_mapping = {
156
+ "null": "string",
157
+ "int": "integer",
158
+ "long": "integer",
159
+ "float": "number",
160
+ "double": "number",
161
+ "boolean": "boolean",
162
+ "bytes": "string",
163
+ "string": "string"
164
+ }
165
+ return scalar_type_mapping.get(type_name, "string")
166
+
167
+ def convert_avro_to_datapackage(avro_schema_path: str, avro_record_type: Optional[str], datapackage_path: str):
168
+ """Convert an Avro schema to a Data Package."""
169
+ converter = AvroToDataPackageConverter()
170
+ converter.convert_avro_to_datapackage(avro_schema_path, avro_record_type, datapackage_path)
171
+
172
+ # Example usage:
173
+ # convert_avro_to_datapackage("schema.avsc", "MyRecord", "datapackage.json")