Source code for optunaz.utils.schema

import collections
from collections.abc import Mapping
import copy
from typing import Union, Dict, List, Any


[docs]def create_dependency(key, value): newkey = f"is_enabled_{key}" title = value.get("title", key) newvalue = { "title": f"Enable {title}", "default": "No", "enum": ["No", "Yes"], } dep = { "oneOf": [ {"properties": {newkey: {"enum": ["No"]}}}, {"properties": {newkey: {"enum": ["Yes"]}, key: value}, "required": [key]}, ] } return newkey, newvalue, dep
[docs]def remove_schema_properties(schema: Dict[str, Any], properties: List[str]) -> None: schemaprops = schema.get("properties", {}) for prop in properties: schemaprops.pop(prop, None)
[docs]def add_boolean_guards_for_schema_properties( schema: Dict[str, Any], properties: List[str] ) -> None: if "dependencies" not in schema: schema["dependencies"] = {} props = schema.get("properties", {}) new_props = {} for key, value in props.items(): if key in properties: newkey, newvalue, dep = create_dependency(key, value) new_props[newkey] = newvalue schema["dependencies"][newkey] = dep else: new_props[key] = value schema["properties"] = new_props
[docs]def replacekey(input_: Union[Dict, List, object]) -> Any: replacements = {"anyOf": "oneOf"} if isinstance(input_, dict): # For every key in the dict, get either a replacement, or the key itself. # Call this function recursively for values. return {replacements.get(k, k): replacekey(v) for k, v in input_.items()} elif isinstance(input_, list): return [replacekey(item) for item in input_] else: return input_
[docs]def replacevalue(input_: Union[Dict, List, object]) -> Any: if isinstance(input_, dict): return {k: replacevalue(input_[k]) for k in input_} elif isinstance(input_, list): return [replacevalue(item) for item in input_] else: replacements = {"integer": "number"} return replacements.get(input_, input_)
[docs]def addsibling(input_: Union[Dict, List, object]) -> Any: if isinstance(input_, dict): d = {k: addsibling(input_[k]) for k in input_} if "oneOf" in input_: d["type"] = "object" return d elif isinstance(input_, list): return [addsibling(item) for item in input_] else: return input_
[docs]def delsibling(input_: Union[Dict, List, object], siblings: Dict[str, str]) -> Any: if isinstance(input_, dict): d = {k: delsibling(input_[k], siblings) for k in input_} for key, value in siblings.items(): if key in input_: d.pop(value, None) return d elif isinstance(input_, list): return [delsibling(item, siblings) for item in input_] else: return input_
[docs]def getref(path: str, context: Dict): """Recursively returns nested items from a dict.""" if not path.startswith("#/"): raise ValueError("ref path does not start with #/") items = path[2:].split("/") def recursive_get(keys, structure): if len(keys) == 0: return structure else: return recursive_get(keys[1:], structure[keys[0]]) return recursive_get(items, context)
[docs]def copytitle(input_, context): """Copies "title" from "$ref" into oneOf.""" if isinstance(input_, dict): output = {} for key in input_: if key == "oneOf": initems = input_[key] outitems = [] for initem in initems: outitem = copy.deepcopy(initem) if "$ref" in initem and not "title" in initem: ref = getref(initem["$ref"], context) default_title = initem["$ref"].split("/")[-1] outitem["title"] = ref.get("title", default_title) outitems.append(outitem) output[key] = outitems else: output[key] = copytitle(input_[key], context) return output elif isinstance(input_, list): return [copytitle(item, context) for item in input_] else: return input_
[docs]def replaceenum(input_: Union[Dict, List, object]) -> Any: """Replace singleton enums with const.""" if isinstance(input_, Mapping): d1 = { k: replaceenum(v) for k, v in input_.items() if not (k == "enum" and isinstance(v, list) and len(v) == 1) } d2 = { "const": v[0] for k, v in input_.items() if (k == "enum" and isinstance(v, list) and len(v) == 1) } return {**d1, **d2} # Merge two dicts: https://stackoverflow.com/a/26853961 elif isinstance(input_, list): return [replaceenum(item) for item in input_] else: return input_
[docs]def addtitles(schema): if isinstance(schema, dict): for name, prop in schema.get("properties", {}).items(): # Skip adding titles to "Parameters", so that GUI can hide extra boxes. if name.capitalize() != "Parameters": prop["title"] = prop.get("title", name.capitalize()) for value in schema.values(): addtitles(value) elif isinstance(schema, list): for elt in schema: addtitles(elt)