def convert_property(prop_name, prop): # it's datetime if "format" in prop and prop["format"] == "date-time": return "xsd:dataTime" # it's another object elif prop.get("type") is None and prop.get("$ref") is not None: prop_type = prop["$ref"].split("/")[-1] if defs is None or prop_type not in defs: raise RuntimeError(f"{prop_type} not found in defs.") if pipe: return self.from_json_schema(prop_type, defs[prop_type], pipe=True) else: self.from_json_schema(prop_type, defs[prop_type], subdoc=True) return self.object[prop_type]._to_dict() # it's enum elif prop.get("type") is None and prop.get("enum") is not None: # create enum name from snake case to camal case enum_name = prop_name.replace("_", " ").capitalize().replace( " ", "") enum_dict = { "@id": enum_name, "@type": "Enum", "@value": prop["enum"] } if pipe: return enum_dict else: self._contruct_class(enum_dict) return self.object[enum_name]._to_dict() # it's a List elif prop["type"] == "array": prop_type = convert_property(prop["items"]) return {"@type": "List", "@class": prop_type} elif isinstance(prop["type"], list): prop_type = prop["type"] # it's Optional if "null" in prop_type: prop_type.remove("null") prop_type = prop_type[0] # can only have one type # it's list in a 'type' so assume no ref return to_woql_type( Optional.__getitem__(convert_dict[prop_type])) # THIS SHOULD BE TaggedUnion # elif len(prop_type) > 1: # prop_type = to_woql_type( # Union.__getitem__(*map(lambda x: convert_dict[x], prop_type)) # ) # type is wrapped in a list else: return to_woql_type(convert_dict[prop_type[0]]) else: return to_woql_type(convert_dict[prop["type"]])
def __make_pydantic(cls): """ Temporary wrapper function to convert an MSONable class into a PyDantic Model for the sake of building schemas """ if any(cls == T for T in built_in_primitives): return cls if cls in prim_to_type_hint: return prim_to_type_hint[cls] if cls == Any: return Any if type(cls) == TypeVar: return cls if hasattr(cls, "__origin__") and hasattr(cls, "__args__"): args = tuple(__make_pydantic(arg) for arg in cls.__args__) if cls.__origin__ == Union: return Union.__getitem__(args) if cls.__origin__ == Optional and len(args) == 1: return Optional.__getitem__(args) if cls._name == "List": return List.__getitem__(args) if cls._name == "Tuple": return Tuple.__getitem__(args) if cls._name == "Set": return Set.__getitem__(args) if cls._name == "Sequence": return Sequence.__getitem__(args) if issubclass(cls, MSONable): if cls.__name__ not in STUBS: STUBS[cls] = MSONable_to_pydantic(cls) return STUBS[cls] if cls == ndarray: return List[Any] return cls