Source code for ossindex.serializer

##
# Copyright 2022-Present Sonatype Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import re
from json import JSONEncoder
from typing import Any, Dict

# See https://github.com/package-url/packageurl-python/issues/65
from packageurl import PackageURL  # type: ignore

from .model import OssIndexComponent, Vulnerability


[docs]def pythonify_key_names(d: Dict[str, Any]) -> Dict[Any, Any]: named_d: Dict[Any, Any] = {} # Covert Key Names for (k, v) in d.items(): new_k = re.sub(r'(?<!^)(?=[A-Z])', '_', k).lower() if k == 'id': # Special case for reserved keyword new_k = 'id_' named_d[new_k] = v return named_d
[docs]def json_decoder(o: object) -> object: if isinstance(o, dict): named_o = pythonify_key_names(d=o) try: if 'coordinates' in named_o.keys(): return OssIndexComponent(**named_o) elif 'id_' in named_o.keys(): return Vulnerability(**named_o) except TypeError as e: print(f'Error was on {o}') raise e raise ValueError( f'Unknown value in JSON being decoded: {o}' )
[docs]_HYPHENATED_ATTRIBUTES = [ 'bom_ref', 'mime_type', 'x_trust_boundary' ]
[docs]_PYTHON_TO_JSON_NAME = re.compile(r'_([a-z])')
[docs]class OssIndexJsonEncoder(JSONEncoder):
[docs] def default(self, o: Any) -> Any: # Sets if isinstance(o, set): return list(o) # Classes if isinstance(o, object): d: Dict[Any, Any] = {} for k, v in o.__dict__.items(): # Remove leading _ in key names new_key = k[1:] if new_key.startswith('_') or '__' in new_key: continue # Convert pythonic names to JSON names # e.g. 'external_references' to 'externalReferences' # # Some special cases are hyphenated, not camel case if new_key in _HYPHENATED_ATTRIBUTES: new_key = new_key.replace('_', '-') elif '_' in new_key: new_key = _PYTHON_TO_JSON_NAME.sub(lambda x: x.group(1).upper(), new_key) if v or v is False: if isinstance(v, PackageURL): # Special handling of PackageURL instances which JSON would otherwise automatically encode to # an Array v = str(v.to_string()) d[new_key] = v return d # Fallback to default super().default(o=o)