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"]])
예제 #2
0
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