Source code for ferrosoft.apps.dataimport.services.fixtures

import importlib
import json
from typing import Iterable, Tuple, Mapping, Callable

from jsonschema.validators import Draft202012Validator

from ferrosoft.apps.dataimport.services.errors import CatalogValidationError, CatalogConversionError

SchemaID = str
"""JSON schema ID"""


[docs] def load_converters(converters_name: str) -> Mapping[SchemaID, Callable]: module_name, member_name = converters_name.rsplit(".", 1) module = importlib.import_module(module_name) converters = getattr(module, member_name, None) if converters is None: raise RuntimeError("Converters not found: %s" % converters_name) if not isinstance(converters, dict): raise RuntimeError("Converters must be dict, got %s" % type(converters)) return converters
[docs] def convert_catalog_files( catalog_file_names: Iterable[str], schema_file_name: str, converters: Mapping[SchemaID, Callable], ) -> list: """ Create fixtures from catalog files. Args: catalog_file_names: JSON catalogs which must conform to JSON schema. schema_file_name: JSON schema file. converters: Converter function for each supported JSON schema: f(catalog) -> fixtures. Returns: Fixtures from all converted catalogs. """ fixtures = [] for catalog_path in catalog_file_names: with open(catalog_path, mode="rb") as catalog_file: catalog = json.load(catalog_file) schema_id, errors = validate_catalog(catalog, schema_file_name) if len(errors) > 0: raise CatalogValidationError( "Invalid catalog file:\n" + "\n".join(errors) ) if schema_id not in converters: raise CatalogConversionError("Cannot convert schema to fixtures: %s" % schema_id) fixtures.append(converters[schema_id](catalog)) # Flatten fixtures. return [x for xs in fixtures for x in xs]
[docs] def validate_catalog( catalog: dict, schema_file_name: str ) -> Tuple[SchemaID, list]: """Validate catalog dict against catalog schema.""" with open(schema_file_name, "rb") as schema_file: schema = json.load(schema_file) schema_id = schema.get("$id", None) validator = Draft202012Validator(schema) return SchemaID(schema_id), [ "%s at %s" % (err.message, err.json_path) for err in validator.iter_errors(instance=catalog) ]