1"""This submodule contains utility code for Prance.""" 2 3__author__ = 'Jens Finkhaeuser' 4__copyright__ = 'Copyright (c) 2016-2021 Jens Finkhaeuser' 5__license__ = 'MIT' 6__all__ = ('iterators', 'fs', 'formats', 'resolver', 'url', 'path', 7 'exceptions') 8 9 10def stringify_keys(data): 11 """ 12 Recursively stringify keys in a dict-like object. 13 14 :param dict-like data: A dict-like object to stringify keys in. 15 :return: A new dict-like object of the same type with stringified keys, 16 but the same values. 17 """ 18 from collections.abc import Mapping 19 assert isinstance(data, Mapping) 20 21 ret = type(data)() 22 for key, value in data.items(): 23 if not isinstance(key, str): 24 key = str(key) 25 if isinstance(value, Mapping): 26 value = stringify_keys(value) 27 ret[key] = value 28 return ret 29 30 31def validation_backends(): 32 """Return a list of validation backends supported by the environment.""" 33 ret = [] 34 35 try: 36 import flex # noqa: F401 37 ret.append('flex') # pragma: nocover 38 except (ImportError, SyntaxError): # pragma: nocover 39 pass 40 41 try: 42 import openapi_spec_validator # noqa: F401 43 ret.append('openapi-spec-validator') # pragma: nocover 44 except (ImportError, SyntaxError): # pragma: nocover 45 pass 46 47 try: 48 import swagger_spec_validator # noqa: F401 49 ret.append('swagger-spec-validator') # pragma: nocover 50 except (ImportError, SyntaxError): # pragma: nocover 51 pass 52 53 return tuple(ret) 54 55 56def default_validation_backend(): 57 """Return the default validation backend, or raise an error.""" 58 backends = validation_backends() 59 if len(backends) <= 0: # pragma: nocover 60 raise RuntimeError('No validation backend available! Install one of ' 61 '"flex", "openapi-spec-validator" or "swagger-spec-validator".') 62 return backends[0] 63