|
5 | 5 | from flask_restx import Resource |
6 | 6 |
|
7 | 7 | from esdlvalidator.api import app |
8 | | -from esdlvalidator.api.controller import validationService |
| 8 | +from esdlvalidator.api.controller import validationService, schemaService |
9 | 9 | from esdlvalidator.core.exceptions import SchemaNotFound |
10 | 10 |
|
11 | 11 | parser = app.api.parser() |
@@ -48,74 +48,108 @@ def post(self): |
48 | 48 | if "schemas" not in request.args: |
49 | 49 | return "Bad Request: Required 'schemas' parameter missing", 400 |
50 | 50 |
|
51 | | - schema_list = [id for id in request.args["schemas"].split(",")] |
| 51 | + # Main schema refs requested by user |
| 52 | + main_schema_refs = [id_or_name for id_or_name in request.args["schemas"].split(",")] |
52 | 53 |
|
53 | 54 | try: |
54 | | - result = validationService.validateContents(file, schema_list) |
| 55 | + main_schema_defs = schemaService.get_by_id_or_name(main_schema_refs) |
| 56 | + |
| 57 | + # Collect all schemas to run |
| 58 | + pre_refs = [] |
| 59 | + post_refs = [] |
| 60 | + for schema in main_schema_defs: |
| 61 | + pre_refs.extend(schema.get("pre_validation_schemas", [])) |
| 62 | + post_refs.extend(schema.get("post_validation_schemas", [])) |
| 63 | + |
| 64 | + # Remove duplicates while preserving order |
| 65 | + def unique(seq): |
| 66 | + return list(dict.fromkeys(seq)) |
| 67 | + |
| 68 | + pre_refs = unique(pre_refs) |
| 69 | + post_refs = unique(post_refs) |
| 70 | + |
| 71 | + # Run validations in order |
| 72 | + results = [] |
| 73 | + |
| 74 | + if pre_refs: |
| 75 | + pre_defs = schemaService.get_by_id_or_name(pre_refs) |
| 76 | + pre_ids = [schema["id"] for schema in pre_defs] |
| 77 | + results.append(validationService.validateContents(file, pre_ids)) |
| 78 | + |
| 79 | + main_ids = [schema["id"] for schema in main_schema_defs] |
| 80 | + results.append(validationService.validateContents(file, main_ids)) |
| 81 | + |
| 82 | + if post_refs: |
| 83 | + post_defs = schemaService.get_by_id_or_name(post_refs) |
| 84 | + post_ids = [schema["id"] for schema in post_defs] |
| 85 | + results.append(validationService.validateContents(file, post_ids)) |
| 86 | + |
55 | 87 | except SchemaNotFound as e: |
56 | 88 | return e.message, e.statusCode |
57 | 89 |
|
58 | 90 | json_result: list[AssetMessage] = [] |
59 | 91 |
|
60 | | - for schema in result["schemas"]: |
61 | | - if "validations" not in schema: |
62 | | - continue |
63 | | - |
64 | | - for validation in schema["validations"]: |
65 | | - for severity_key in ["errors", "warnings"]: |
66 | | - severity = severity_key.rstrip("s").upper() |
67 | | - |
68 | | - if severity_key in validation: |
69 | | - for issue in validation[severity_key]: |
70 | | - asset_id = issue.get("offending_asset") |
71 | | - |
72 | | - if asset_id is None: |
73 | | - raise KeyError( |
74 | | - f"Can not associate message with an asset as 'offending_asset' key not found." |
75 | | - ) |
76 | | - |
77 | | - message = issue.get("message") |
78 | | - if isinstance(message, dict): |
79 | | - validation_msg = message.get("validation_message", "") |
80 | | - check_msgs = message.get("check_result_message", []) |
81 | | - if isinstance(check_msgs, str): |
82 | | - check_msgs = [check_msgs] |
83 | | - else: |
84 | | - validation_msg = "" |
85 | | - check_msgs = [str(message)] |
86 | | - |
87 | | - asset_message = self.get_asset_message(asset_id, json_result) |
88 | | - |
89 | | - if asset_message is None: |
90 | | - new_asset_message = AssetMessage( |
91 | | - assetID=asset_id, |
92 | | - messages=[ |
93 | | - ValidationResult( |
94 | | - severity=severity, |
95 | | - validation_message=validation_msg, |
96 | | - check_result_messages=check_msgs, |
97 | | - ) |
98 | | - ], |
99 | | - ) |
100 | | - json_result.append(new_asset_message) |
101 | | - |
102 | | - else: |
103 | | - # Try to find existing validation_message entry and extend its check_result_messages |
104 | | - matched = False |
105 | | - for v_result in asset_message["messages"]: |
106 | | - if v_result["validation_message"] == validation_msg: |
107 | | - v_result["check_result_messages"].extend(check_msgs) |
108 | | - matched = True |
109 | | - break |
110 | | - |
111 | | - if not matched: |
112 | | - asset_message["messages"].append( |
113 | | - ValidationResult( |
114 | | - severity=severity, |
115 | | - validation_message=validation_msg, |
116 | | - check_result_messages=check_msgs, |
117 | | - ) |
| 92 | + for result in results: |
| 93 | + for schema in result.get("schemas", []): |
| 94 | + if "validations" not in schema: |
| 95 | + continue |
| 96 | + |
| 97 | + for validation in schema["validations"]: |
| 98 | + for severity_key in ["errors", "warnings"]: |
| 99 | + severity = severity_key.rstrip("s").upper() |
| 100 | + |
| 101 | + if severity_key in validation: |
| 102 | + for issue in validation[severity_key]: |
| 103 | + # TODO: handle issue is a string |
| 104 | + asset_id = issue.get("offending_asset") |
| 105 | + |
| 106 | + if asset_id is None: |
| 107 | + raise KeyError( |
| 108 | + f"Can not associate message with an asset as 'offending_asset' key not found." |
| 109 | + ) |
| 110 | + |
| 111 | + message = issue.get("message") |
| 112 | + if isinstance(message, dict): |
| 113 | + validation_msg = message.get("validation_message", "") |
| 114 | + check_msgs = message.get("check_result_message", []) |
| 115 | + if isinstance(check_msgs, str): |
| 116 | + check_msgs = [check_msgs] |
| 117 | + else: |
| 118 | + validation_msg = "" |
| 119 | + check_msgs = [str(message)] |
| 120 | + |
| 121 | + asset_message = self.get_asset_message(asset_id, json_result) |
| 122 | + |
| 123 | + if asset_message is None: |
| 124 | + new_asset_message = AssetMessage( |
| 125 | + assetID=asset_id, |
| 126 | + messages=[ |
| 127 | + ValidationResult( |
| 128 | + severity=severity, |
| 129 | + validation_message=validation_msg, |
| 130 | + check_result_messages=check_msgs, |
| 131 | + ) |
| 132 | + ], |
118 | 133 | ) |
| 134 | + json_result.append(new_asset_message) |
| 135 | + |
| 136 | + else: |
| 137 | + # Try to find existing validation_message entry and extend its check_result_messages |
| 138 | + matched = False |
| 139 | + for v_result in asset_message["messages"]: |
| 140 | + if v_result["validation_message"] == validation_msg: |
| 141 | + v_result["check_result_messages"].extend(check_msgs) |
| 142 | + matched = True |
| 143 | + break |
| 144 | + |
| 145 | + if not matched: |
| 146 | + asset_message["messages"].append( |
| 147 | + ValidationResult( |
| 148 | + severity=severity, |
| 149 | + validation_message=validation_msg, |
| 150 | + check_result_messages=check_msgs, |
| 151 | + ) |
| 152 | + ) |
119 | 153 |
|
120 | 154 | return Response(response=json.dumps(json_result), status=200, mimetype="text/json") |
121 | 155 |
|
|
0 commit comments