pyegeria 5.4.0.13__py3-none-any.whl → 5.4.0.15__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.
- commands/cat/debug_log +540 -0
- commands/cat/list_format_set.py +15 -9
- pyegeria/_output_format_models.py +373 -0
- pyegeria/_output_formats.py +478 -190
- pyegeria/collection_manager_omvs.py +1 -1
- pyegeria/governance_officer_omvs.py +2 -2
- pyegeria/load_config.py +38 -13
- pyegeria/logging_configuration.py +2 -2
- {pyegeria-5.4.0.13.dist-info → pyegeria-5.4.0.15.dist-info}/METADATA +1 -1
- {pyegeria-5.4.0.13.dist-info → pyegeria-5.4.0.15.dist-info}/RECORD +13 -14
- md_processing/dr-egeria-outbox/DataStruct-2025-07-29-20-49-16.py +0 -8
- md_processing/dr-egeria-outbox/Mandy-DataStruct-2025-07-29-15-54-45.md +0 -19
- pyegeria/dr.egeria spec.md +0 -9
- {pyegeria-5.4.0.13.dist-info → pyegeria-5.4.0.15.dist-info}/LICENSE +0 -0
- {pyegeria-5.4.0.13.dist-info → pyegeria-5.4.0.15.dist-info}/WHEEL +0 -0
- {pyegeria-5.4.0.13.dist-info → pyegeria-5.4.0.15.dist-info}/entry_points.txt +0 -0
pyegeria/_output_formats.py
CHANGED
@@ -10,194 +10,322 @@ This file manages output format sets.
|
|
10
10
|
pyegeria allows find and get requests to generate output in different output formats -
|
11
11
|
including DICT, MD, FORM, REPORT, LIST, MERMAID, TABLE, and perhaps additional ones in the future.
|
12
12
|
|
13
|
-
|
13
|
+
It is important to be able to filter which attributes to
|
14
14
|
display, and the order in which they appear. However, many, if not most users will likely not want to customize
|
15
15
|
the column list and so we need a sensible set of defaults for each type of output. These defaults are used
|
16
16
|
by the find and get methods if the user doesn't provide a value for the columns parameter.
|
17
17
|
|
18
|
-
This file contains these defaults and
|
18
|
+
This file contains these defaults and functions to work with them. The output format sets are now implemented
|
19
|
+
using Pydantic models defined in `_output_format_models.py`, which provide several advantages:
|
20
|
+
- Type validation: The models ensure that the data has the correct types and structure.
|
21
|
+
- Composition: The models support composition of formats, allowing formats to be reused and combined.
|
22
|
+
- Documentation: The models provide clear documentation of the data structure.
|
23
|
+
- IDE support: The models provide better IDE support, including autocompletion and type hints.
|
24
|
+
|
25
|
+
The functions in this module are designed to be backward compatible with code that expects the old
|
26
|
+
dictionary-based format. They convert between Pydantic models and dictionaries as needed.
|
27
|
+
|
28
|
+
Example usage:
|
29
|
+
```python
|
30
|
+
# Get a format set by name and output type
|
31
|
+
format_set = select_output_format_set("Collections", "TABLE")
|
32
|
+
|
33
|
+
# Get a list of all available format sets
|
34
|
+
format_sets = output_format_set_list()
|
35
|
+
|
36
|
+
# Get the heading and description of a format set
|
37
|
+
heading = get_output_format_set_heading("Collections")
|
38
|
+
description = get_output_format_set_description("Collections")
|
39
|
+
|
40
|
+
# Match a format set with a specific output type
|
41
|
+
matched_format_set = get_output_format_type_match(format_set, "DICT")
|
42
|
+
```
|
43
|
+
|
44
|
+
For more advanced usage, you can work directly with the Pydantic models:
|
45
|
+
```python
|
46
|
+
from pyegeria._output_format_models import Column, Format, FormatSet
|
47
|
+
|
48
|
+
# Create a new format set
|
49
|
+
format_set = FormatSet(
|
50
|
+
heading="Example Format Set",
|
51
|
+
description="An example format set",
|
52
|
+
formats=[
|
53
|
+
Format(
|
54
|
+
types=["TABLE", "DICT"],
|
55
|
+
columns=[
|
56
|
+
Column(name="Display Name", key="display_name"),
|
57
|
+
Column(name="Description", key="description", format=True),
|
58
|
+
],
|
59
|
+
),
|
60
|
+
],
|
61
|
+
)
|
62
|
+
|
63
|
+
# Add the format set to the output_format_sets dictionary
|
64
|
+
output_format_sets["Example"] = format_set
|
65
|
+
```
|
19
66
|
"""
|
20
67
|
|
68
|
+
import os
|
69
|
+
from pathlib import Path
|
70
|
+
from typing import Dict, List, Optional, Union, Any
|
21
71
|
from loguru import logger
|
22
72
|
|
73
|
+
from pyegeria._output_format_models import Column, Format, ActionParameter, FormatSet, FormatSetDict, save_format_sets_to_json, load_format_sets_from_json
|
74
|
+
from pyegeria.load_config import get_app_config
|
75
|
+
|
76
|
+
# Get the configured value for the user format sets directory
|
77
|
+
app_config = get_app_config()
|
78
|
+
USER_FORMAT_SETS_DIR = os.path.expanduser(app_config.Environment.pyegeria_user_format_sets_dir)
|
79
|
+
|
23
80
|
# Constants
|
24
81
|
MD_SEPARATOR = "\n---\n\n"
|
25
82
|
|
26
83
|
# Define shared elements
|
27
84
|
COMMON_COLUMNS = [
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
85
|
+
Column(name='Display Name', key='display_name'),
|
86
|
+
Column(name='Qualified Name', key='qualified_name', format=True),
|
87
|
+
Column(name='Category', key='category'),
|
88
|
+
Column(name='Description', key='description', format=True),
|
32
89
|
]
|
33
90
|
|
34
91
|
COMMON_METADATA_COLUMNS = [
|
35
|
-
|
36
|
-
|
37
|
-
|
92
|
+
Column(name='GUID', key='guid', format=True),
|
93
|
+
Column(name='Metadata Collection ID', key='metadata_collection_id', format=True),
|
94
|
+
Column(name='Metadata Collection Name', key='metadata_collection_name', format=True),
|
38
95
|
]
|
39
96
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
97
|
+
COMMON_HEADER_COLUMNS = [
|
98
|
+
Column(name="Classifications", key='classifications'),
|
99
|
+
Column(name="Created By", key='created_by'),
|
100
|
+
Column(name="Create Time", key='create_time'),
|
101
|
+
Column(name="Updated By", key='updated_by'),
|
102
|
+
Column(name="Update Time", key='update_time'),
|
103
|
+
Column(name="Effective From", key='effective_from'),
|
104
|
+
Column(name="Effective To", key='effective_to'),
|
105
|
+
Column(name="Version", key='version'),
|
106
|
+
Column(name="Open Metadata Type Name", key='type_name'),
|
107
|
+
]
|
108
|
+
|
109
|
+
|
110
|
+
REFERNCEABLE_COLUMNS = COMMON_COLUMNS + [
|
111
|
+
Column(name='Version Identifier', key='version_identifier'),
|
112
|
+
Column(name='Additional Properties', key='additional_properties')
|
113
|
+
]
|
114
|
+
|
115
|
+
|
116
|
+
COMMON_FORMATS_ALL = Format(
|
117
|
+
types=["ALL"],
|
118
|
+
columns=COMMON_COLUMNS,
|
119
|
+
)
|
120
|
+
|
121
|
+
|
122
|
+
COLLECTIONS_COLUMNS = COMMON_COLUMNS + [
|
123
|
+
Column(name="Created By", key='created_by'),
|
124
|
+
Column(name="Create Time", key='create_time'),
|
125
|
+
Column(name="Updated By", key='updated_by'),
|
126
|
+
Column(name="Update Time", key='update_time'),
|
127
|
+
]
|
44
128
|
|
129
|
+
COLLECTIONS_MEMBERS_COLUMNS = COLLECTIONS_COLUMNS + [
|
130
|
+
Column(name="Members", key='members'),
|
131
|
+
]
|
45
132
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
{'name': "Update Time", 'key': 'update_time'},
|
51
|
-
]
|
133
|
+
COLLECTION_DICT = Format(
|
134
|
+
types=["DICT"],
|
135
|
+
columns=COLLECTIONS_COLUMNS,
|
136
|
+
)
|
52
137
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
138
|
+
COLLECTION_TABLE = Format(
|
139
|
+
types=["TABLE"],
|
140
|
+
columns=COMMON_COLUMNS,
|
141
|
+
)
|
57
142
|
|
58
|
-
|
59
|
-
"
|
60
|
-
"
|
61
|
-
|
143
|
+
GOVERNANCE_DEFINITIONS_COLUMNS = COMMON_COLUMNS + [
|
144
|
+
Column(name="Document Identifier", key='document_identifier'),
|
145
|
+
Column(name="Title", key='title'),
|
146
|
+
Column(name="Scope", key='scope'),
|
147
|
+
]
|
62
148
|
|
63
149
|
COMMON_ANNOTATIONS = {
|
64
150
|
"wikilinks": ["[[Commons]]"]
|
65
151
|
}
|
66
152
|
|
67
153
|
# Modularized output_format_sets
|
68
|
-
output_format_sets = {
|
69
|
-
"Referenceable":
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
154
|
+
output_format_sets = FormatSetDict({
|
155
|
+
"Referenceable": FormatSet(
|
156
|
+
heading="Common Attributes",
|
157
|
+
description="Attributes that apply to all Referenceables.",
|
158
|
+
annotations={}, # No specific annotations
|
159
|
+
formats=[
|
160
|
+
Format(
|
161
|
+
types=["ALL"],
|
162
|
+
columns=COMMON_COLUMNS + COMMON_METADATA_COLUMNS + [
|
163
|
+
Column(name='Version Identifier', key='version_identifier'),
|
164
|
+
Column(name="Classifications", key='classifications'),
|
165
|
+
Column(name="Additional Properties", key='additional_properties'),
|
166
|
+
Column(name="Created By", key='created_by'),
|
167
|
+
Column(name="Create Time", key='create_time'),
|
168
|
+
Column(name="Updated By", key='updated_by'),
|
169
|
+
Column(name="Update Time", key='update_time'),
|
170
|
+
Column(name="Effective From", key='effective_from'),
|
171
|
+
Column(name="Effective To", key='effective_to'),
|
172
|
+
Column(name="Version", key='version'),
|
173
|
+
Column(name="Open Metadata Type Name", key='type_name'),
|
88
174
|
],
|
89
|
-
|
175
|
+
)
|
90
176
|
],
|
91
|
-
|
92
|
-
|
93
|
-
"Collections":
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
}
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
"
|
109
|
-
"
|
110
|
-
"
|
111
|
-
"
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
177
|
+
),
|
178
|
+
|
179
|
+
"Collections": FormatSet(
|
180
|
+
heading="Common Collection Information",
|
181
|
+
description="Attributes generic to all Collections.",
|
182
|
+
aliases=["Collection", "RootCollection", "Folder", "ReferenceList", "HomeCollection",
|
183
|
+
"ResultSet", "RecentAccess", "WorkItemList", "Namespace"],
|
184
|
+
annotations=COMMON_ANNOTATIONS,
|
185
|
+
formats=[COLLECTION_DICT, COLLECTION_TABLE, COMMON_FORMATS_ALL], # Reusing common formats
|
186
|
+
action=[ActionParameter(
|
187
|
+
function="CollectionManager.find_collections",
|
188
|
+
user_params=["search_string"],
|
189
|
+
spec_params={},
|
190
|
+
)]
|
191
|
+
),
|
192
|
+
|
193
|
+
"CollectionMembers": FormatSet(
|
194
|
+
heading="Collection Membership Information",
|
195
|
+
description="Attributes about all CollectionMembers.",
|
196
|
+
aliases=["CollectionMember", "Member", "Members"],
|
197
|
+
annotations= {"wikilinks": ["[[CollectionMembers]]"]},
|
198
|
+
formats = [COLLECTION_DICT, COLLECTION_TABLE],
|
199
|
+
action=[ActionParameter(
|
200
|
+
function="CollectionManager.get_collection_members",
|
201
|
+
user_params=["collection_guid"],
|
202
|
+
spec_params={"output_format": "DICT"},
|
203
|
+
)]
|
204
|
+
),
|
205
|
+
"DigitalProducts": FormatSet(
|
206
|
+
heading="Digital Product Information",
|
207
|
+
description="Attributes useful to Digital Products.",
|
208
|
+
aliases=["DigitalProduct", "DataProducts"],
|
209
|
+
annotations={},
|
210
|
+
formats=[
|
211
|
+
Format(
|
212
|
+
types=["REPORT"],
|
213
|
+
columns=COMMON_COLUMNS + [
|
214
|
+
Column(name="Status", key='status'),
|
215
|
+
Column(name='Product Name', key='product_name'),
|
216
|
+
Column(name='Identifier', key='identifier'),
|
217
|
+
Column(name='Maturity', key='maturity'),
|
218
|
+
Column(name='Service Life', key='service_life'),
|
219
|
+
Column(name='Next Version', key='next_version'),
|
220
|
+
Column(name='Withdraw Date', key='withdraw_date'),
|
221
|
+
Column(name='Members', key='members', format=True),
|
123
222
|
],
|
124
|
-
|
223
|
+
)
|
125
224
|
],
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
]
|
131
|
-
|
132
|
-
|
133
|
-
"Agreements":
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
"DataDictionary":
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
}
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
"
|
156
|
-
"
|
157
|
-
"
|
158
|
-
"
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
"
|
176
|
-
"
|
177
|
-
"
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
"
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
225
|
+
action=[ActionParameter(
|
226
|
+
function="CollectionManager.find_collections",
|
227
|
+
user_params=["search_string"],
|
228
|
+
spec_params={"classification_name": "DigitalProducts"},
|
229
|
+
)]
|
230
|
+
),
|
231
|
+
|
232
|
+
"Agreements": FormatSet(
|
233
|
+
heading="General Agreement Information",
|
234
|
+
description="Attributes generic to all Agreements.",
|
235
|
+
aliases=["DataSharingAgreement"],
|
236
|
+
annotations={"wikilinks": ["[[Agreements]]", "[[Egeria]]"]},
|
237
|
+
formats=[COMMON_FORMATS_ALL] # Reusing common formats and columns
|
238
|
+
),
|
239
|
+
|
240
|
+
"DataDictionary": FormatSet(
|
241
|
+
heading="Data Dictionary Information",
|
242
|
+
description="Attributes useful to Data Dictionary.",
|
243
|
+
aliases=["Data Dict", "Data Dictionary"],
|
244
|
+
annotations={"wikilinks": ["[[Data Dictionary]]"]},
|
245
|
+
formats=[COMMON_FORMATS_ALL], # Reusing common formats and columns
|
246
|
+
action=[ActionParameter(
|
247
|
+
function="CollectionManager.find_collections",
|
248
|
+
user_params=["search_string"],
|
249
|
+
spec_params={"classification_name": "DataDictionary"},
|
250
|
+
)]
|
251
|
+
),
|
252
|
+
|
253
|
+
"Data Specification": FormatSet(
|
254
|
+
heading="Data Specification Information",
|
255
|
+
description="Attributes useful to Data Specification.",
|
256
|
+
aliases=["Data Spec", "DataSpec", "DataSpecification"],
|
257
|
+
annotations={"wikilinks": ["[[Data Specification]]"]},
|
258
|
+
formats=[
|
259
|
+
Format(types=["REPORT", "HTML"],columns=COMMON_COLUMNS + [Column(name="Mermaid", key='mermaid'),]),
|
260
|
+
Format(types=["MERMAID"], columns=[
|
261
|
+
Column(name="Display Name", key='display_name'),
|
262
|
+
Column(name="Mermaid", key='mermaid'),
|
263
|
+
]),
|
264
|
+
Format(types=["ALL"], columns=COMMON_COLUMNS)], # Reusing common formats and columns
|
265
|
+
action=[ActionParameter(
|
266
|
+
function="CollectionManager.find_collections",
|
267
|
+
user_params=["search_string"],
|
268
|
+
spec_params={"classification_name": "DataSpec"},
|
269
|
+
)]
|
270
|
+
),
|
271
|
+
|
272
|
+
"DataStruct": FormatSet(
|
273
|
+
heading="Data Structure Information",
|
274
|
+
description="Attributes useful to Data Structures.",
|
275
|
+
aliases=["Data Structure", "DataStructures", "Data Structures", "Data Struct", "DataStructure"],
|
276
|
+
annotations={"wikilinks": ["[[Data Structure]]"]},
|
277
|
+
formats=[Format(types=["ALL"], columns=COMMON_COLUMNS)], # Reusing common formats and columns
|
278
|
+
action=[ActionParameter(
|
279
|
+
function="DataDesigner.find_data_structures",
|
280
|
+
user_params=["search_string"],
|
281
|
+
spec_params={},
|
282
|
+
)]
|
283
|
+
),
|
284
|
+
|
285
|
+
"DataField": FormatSet(
|
286
|
+
heading="Data Structure Information",
|
287
|
+
description="Attributes useful to Data Structures.",
|
288
|
+
aliases=["Data Field", "Data Fields", "DataFields"],
|
289
|
+
annotations={"wikilinks": ["[[Data Field]]"]},
|
290
|
+
formats=[Format(types=["ALL"], columns=COMMON_COLUMNS)], # Reusing common formats and columns
|
291
|
+
action=[ActionParameter(
|
292
|
+
function="DataDesigner.find_data_fields",
|
293
|
+
user_params=["search_string"],
|
294
|
+
spec_params={},
|
295
|
+
)]
|
296
|
+
),
|
297
|
+
|
298
|
+
"Mandy-DataStruct": FormatSet(
|
299
|
+
heading="Puddy Approves",
|
300
|
+
description="This is a tutorial on how to use a data struct description",
|
301
|
+
aliases=[],
|
302
|
+
annotations={"wikilinks": ["[[Data Structure]]"]},
|
303
|
+
formats=[
|
304
|
+
Format(types=["TABLE"], columns=COMMON_COLUMNS + [Column(name='GUID', key='GUID')]),
|
305
|
+
Format(types=[ "DICT","LIST", ], columns=COMMON_COLUMNS + [Column(name='GUID', key='GUID')]),
|
306
|
+
Format(types=["REPORT","MERMAID", "HTML"], columns=[Column(name='Display Name', key='display_name'),
|
307
|
+
Column(name='Mermaid', key='mermaid'),]),
|
308
|
+
],
|
309
|
+
action=[ActionParameter(
|
310
|
+
function="DataDesigner.find_data_structures",
|
311
|
+
user_params=["search_string"],
|
312
|
+
spec_params={"output_format":"DICT"},
|
313
|
+
)]
|
314
|
+
),
|
315
|
+
|
316
|
+
"Governance Definitions": FormatSet(
|
317
|
+
heading="Governance-Definitions Information",
|
318
|
+
description="Attributes useful to Governance-Definitions.",
|
319
|
+
aliases=["GovernanceDefinitions"],
|
320
|
+
annotations={"wikilinks": ["[[Governance]]"]},
|
321
|
+
formats=[Format(types=["ALL"], columns=GOVERNANCE_DEFINITIONS_COLUMNS)],
|
322
|
+
action=[ActionParameter(
|
323
|
+
function="GovernanceOfficer.find_governance_definitions",
|
324
|
+
user_params=["search_filter"],
|
325
|
+
spec_params={"output_format":"DICT"},
|
326
|
+
)]
|
327
|
+
),
|
328
|
+
})
|
201
329
|
|
202
330
|
def select_output_format_set(kind: str, output_type: str) -> dict | None:
|
203
331
|
"""
|
@@ -212,75 +340,235 @@ def select_output_format_set(kind: str, output_type: str) -> dict | None:
|
|
212
340
|
dict | None:
|
213
341
|
"""
|
214
342
|
# Normalize the output type to uppercase for consistency
|
215
|
-
output_sets = output_format_sets
|
216
|
-
|
217
343
|
output_type = output_type.upper()
|
218
|
-
output_struct:dict = {}
|
344
|
+
output_struct: dict = {}
|
219
345
|
|
220
346
|
# Step 1: Check if `kind` exists in the `output_format_sets` dictionary
|
221
|
-
element =
|
347
|
+
element = output_format_sets.get(kind)
|
222
348
|
|
223
349
|
# Step 2: If not found, attempt to match `kind` in aliases
|
224
350
|
if element is None:
|
225
|
-
for value in output_format_sets.
|
226
|
-
aliases = value.
|
351
|
+
for key, value in output_format_sets.items():
|
352
|
+
aliases = value.aliases
|
227
353
|
if kind in aliases:
|
228
354
|
element = value
|
229
355
|
break
|
230
356
|
|
231
|
-
|
232
357
|
# Step 3: If still not found, return None
|
233
358
|
if element is None:
|
234
359
|
msg = f"No matching column set found for kind='{kind}' and output type='{output_type}'."
|
235
360
|
logger.error(msg)
|
236
361
|
return None
|
237
362
|
else:
|
238
|
-
|
239
|
-
output_struct["
|
240
|
-
output_struct["
|
241
|
-
output_struct["
|
242
|
-
|
243
|
-
|
363
|
+
# Convert FormatSet to dictionary for backward compatibility
|
364
|
+
output_struct["aliases"] = element.aliases
|
365
|
+
output_struct["heading"] = element.heading
|
366
|
+
output_struct["description"] = element.description
|
367
|
+
output_struct["annotations"] = element.annotations
|
368
|
+
if element.action:
|
369
|
+
# Convert ActionParameter to dictionary for backward compatibility
|
370
|
+
output_struct["action"] = [action.dict() for action in element.action]
|
244
371
|
|
245
372
|
# If this was just a validation that the format set could be found then the output type is ANY - so just return.
|
246
373
|
if output_type == "ANY":
|
247
374
|
return output_struct
|
248
375
|
|
249
376
|
# Step 4: Search for a matching format in the `formats` list
|
250
|
-
for format in element.
|
251
|
-
if output_type in format.
|
252
|
-
|
377
|
+
for format in element.formats:
|
378
|
+
if output_type in format.types:
|
379
|
+
# Convert Format to dictionary for backward compatibility
|
380
|
+
output_struct["formats"] = format.dict()
|
253
381
|
return output_struct
|
254
382
|
|
255
383
|
# Step 5: Handle the fallback case of "ALL"
|
256
|
-
for format in element.
|
257
|
-
if "ALL" in format.
|
258
|
-
|
384
|
+
for format in element.formats:
|
385
|
+
if "ALL" in format.types:
|
386
|
+
# Convert Format to dictionary for backward compatibility
|
387
|
+
output_struct["formats"] = format.dict()
|
259
388
|
return output_struct
|
260
389
|
|
261
390
|
# Step 6: If no match is found, return None
|
262
391
|
logger.error(f"No matching format found for kind='{kind}' with output type='{output_type}'.")
|
263
392
|
return None
|
264
393
|
|
265
|
-
def output_format_set_list()->list[str]:
|
394
|
+
def output_format_set_list() -> list[str]:
|
395
|
+
"""
|
396
|
+
Returns a list of all available format set names.
|
397
|
+
|
398
|
+
Returns:
|
399
|
+
list[str]: A list of format set names
|
400
|
+
"""
|
266
401
|
return list(output_format_sets.keys())
|
267
402
|
|
268
|
-
def get_output_format_set_heading(format_set:
|
269
|
-
|
270
|
-
|
271
|
-
|
403
|
+
def get_output_format_set_heading(format_set: str) -> str:
|
404
|
+
"""
|
405
|
+
Gets the heading of a format set.
|
406
|
+
|
407
|
+
Args:
|
408
|
+
format_set: The name of the format set
|
409
|
+
|
410
|
+
Returns:
|
411
|
+
str: The heading of the format set
|
412
|
+
"""
|
413
|
+
return output_format_sets[format_set].heading
|
414
|
+
|
415
|
+
def get_output_format_set_description(format_set: str) -> str:
|
416
|
+
"""
|
417
|
+
Gets the description of a format set.
|
418
|
+
|
419
|
+
Args:
|
420
|
+
format_set: The name of the format set
|
421
|
+
|
422
|
+
Returns:
|
423
|
+
str: The description of the format set
|
424
|
+
"""
|
425
|
+
return output_format_sets[format_set].description
|
272
426
|
|
273
|
-
def get_output_format_type_match(format_set: dict, output_format: str) -> dict:
|
274
|
-
|
275
|
-
|
427
|
+
def get_output_format_type_match(format_set: Union[dict, FormatSet], output_format: str) -> dict:
|
428
|
+
"""
|
429
|
+
Matches a format set with a specific output format.
|
430
|
+
|
431
|
+
Args:
|
432
|
+
format_set: The format set to match, either a FormatSet instance or a dictionary
|
433
|
+
output_format: The output format to match
|
434
|
+
|
435
|
+
Returns:
|
436
|
+
dict: The format set with the matching format
|
437
|
+
"""
|
438
|
+
# Convert FormatSet to dictionary if needed
|
439
|
+
if isinstance(format_set, FormatSet):
|
440
|
+
format_set_dict = format_set.dict()
|
441
|
+
else:
|
442
|
+
format_set_dict = format_set
|
443
|
+
|
444
|
+
# Handle the case where format_set is a list (legacy code)
|
445
|
+
if isinstance(format_set_dict, list):
|
446
|
+
for format in format_set_dict.get("formats", []):
|
276
447
|
if output_format in format.get("types", []):
|
277
|
-
|
278
|
-
return
|
448
|
+
format_set_dict["formats"] = format
|
449
|
+
return format_set_dict
|
279
450
|
|
280
|
-
#
|
281
|
-
for format in
|
451
|
+
# Handle the fallback case of "ALL"
|
452
|
+
for format in format_set_dict.get("formats", []):
|
282
453
|
if "ALL" in format.get("types", []):
|
283
|
-
|
284
|
-
return
|
454
|
+
format_set_dict["formats"] = format
|
455
|
+
return format_set_dict
|
456
|
+
else:
|
457
|
+
# Handle the case where format_set is a dictionary
|
458
|
+
if "formats" in format_set_dict:
|
459
|
+
formats = format_set_dict["formats"]
|
460
|
+
if isinstance(formats, list):
|
461
|
+
for format in formats:
|
462
|
+
if output_format in format.get("types", []):
|
463
|
+
format_set_dict["formats"] = format
|
464
|
+
return format_set_dict
|
465
|
+
|
466
|
+
# Handle the fallback case of "ALL"
|
467
|
+
for format in formats:
|
468
|
+
if "ALL" in format.get("types", []):
|
469
|
+
format_set_dict["formats"] = format
|
470
|
+
return format_set_dict
|
471
|
+
else:
|
472
|
+
# Handle the case where format_set is a dictionary from select_output_format_set with the "ANY" output type
|
473
|
+
# In this case, we need to look up the format set by name and get the formats
|
474
|
+
if "heading" in format_set_dict and "description" in format_set_dict:
|
475
|
+
# Try to find the format set by heading
|
476
|
+
for key, value in output_format_sets.items():
|
477
|
+
if value.heading == format_set_dict["heading"] and value.description == format_set_dict["description"]:
|
478
|
+
# Found the format set, now find the matching format
|
479
|
+
for format in value.formats:
|
480
|
+
if output_format in format.types:
|
481
|
+
format_set_dict["formats"] = format.dict()
|
482
|
+
return format_set_dict
|
483
|
+
|
484
|
+
# Handle the fallback case of "ALL"
|
485
|
+
for format in value.formats:
|
486
|
+
if "ALL" in format.types:
|
487
|
+
format_set_dict["formats"] = format.dict()
|
488
|
+
return format_set_dict
|
489
|
+
|
490
|
+
# If no match is found, return the original format set
|
491
|
+
return format_set_dict
|
492
|
+
|
493
|
+
def save_output_format_sets(file_path: str, format_set_names: List[str] = None) -> None:
|
494
|
+
"""
|
495
|
+
Save output format sets to a JSON file.
|
496
|
+
|
497
|
+
This function allows saving all format sets or a subset of format sets to a JSON file.
|
498
|
+
The saved format sets can later be loaded using the `load_output_format_sets` function.
|
499
|
+
|
500
|
+
Args:
|
501
|
+
file_path: The path to save the file to
|
502
|
+
format_set_names: Optional list of format set names to save. If None, all format sets are saved.
|
503
|
+
"""
|
504
|
+
if format_set_names is None:
|
505
|
+
# Save all format sets
|
506
|
+
output_format_sets.save_to_json(file_path)
|
507
|
+
logger.info(f"All format sets saved to {file_path}")
|
285
508
|
else:
|
286
|
-
|
509
|
+
# Save only specified format sets
|
510
|
+
subset = FormatSetDict()
|
511
|
+
for name in format_set_names:
|
512
|
+
format_set = output_format_sets.get(name)
|
513
|
+
if format_set:
|
514
|
+
subset[name] = format_set
|
515
|
+
else:
|
516
|
+
logger.warning(f"Format set '{name}' not found, skipping")
|
517
|
+
|
518
|
+
if subset:
|
519
|
+
subset.save_to_json(file_path)
|
520
|
+
logger.info(f"Selected format sets saved to {file_path}")
|
521
|
+
else:
|
522
|
+
logger.warning(f"No valid format sets to save, file not created")
|
523
|
+
|
524
|
+
def load_output_format_sets(file_path: str, merge: bool = True) -> None:
|
525
|
+
"""
|
526
|
+
Load output format sets from a JSON file.
|
527
|
+
|
528
|
+
This function loads format sets from a JSON file and either merges them with the existing
|
529
|
+
format sets or replaces the existing format sets.
|
530
|
+
|
531
|
+
Args:
|
532
|
+
file_path: The path to load the file from
|
533
|
+
merge: If True, merge with existing format sets. If False, replace existing format sets.
|
534
|
+
"""
|
535
|
+
global output_format_sets
|
536
|
+
try:
|
537
|
+
loaded_sets = FormatSetDict.load_from_json(file_path)
|
538
|
+
|
539
|
+
if merge:
|
540
|
+
# Merge with existing format sets
|
541
|
+
for key, value in loaded_sets.items():
|
542
|
+
output_format_sets[key] = value
|
543
|
+
logger.info(f"Format sets from {file_path} merged with existing format sets")
|
544
|
+
else:
|
545
|
+
# Replace existing format sets
|
546
|
+
output_format_sets = loaded_sets
|
547
|
+
logger.info(f"Existing format sets replaced with format sets from {file_path}")
|
548
|
+
except Exception as e:
|
549
|
+
logger.error(f"Error loading format sets from {file_path}: {e}")
|
550
|
+
raise
|
551
|
+
|
552
|
+
def load_user_format_sets() -> None:
|
553
|
+
"""
|
554
|
+
Load all user-defined format sets from the user format sets directory.
|
555
|
+
|
556
|
+
This function loads all JSON files in the user format sets directory and merges
|
557
|
+
the format sets with the existing format sets.
|
558
|
+
"""
|
559
|
+
if not os.path.exists(USER_FORMAT_SETS_DIR):
|
560
|
+
logger.debug(f"User format sets directory {USER_FORMAT_SETS_DIR} does not exist")
|
561
|
+
return
|
562
|
+
|
563
|
+
# Load all JSON files in the directory
|
564
|
+
for file_path in Path(USER_FORMAT_SETS_DIR).glob("*.json"):
|
565
|
+
try:
|
566
|
+
load_output_format_sets(str(file_path), merge=True)
|
567
|
+
except Exception as e:
|
568
|
+
logger.error(f"Error loading format sets from {file_path}: {e}")
|
569
|
+
|
570
|
+
# Load user-defined format sets at module initialization
|
571
|
+
try:
|
572
|
+
load_user_format_sets()
|
573
|
+
except Exception as e:
|
574
|
+
logger.error(f"Error loading user-defined format sets: {e}")
|