(type_)
Convert a python type hint to its JSON schema representations

    Note that a type hint may actually have several possible representations,
    which is why this function returns a list of schemas. An example of this is
    the `Union` type hint. These are later combined via `wrap_with_any_of()`
Convert a python type hint to its JSON schema representations
Convert a python type hint to its JSON schema representations
def python_type_to_json_schemas(type_):
    """Convert a python type hint to its JSON schema representations

    Note that a type hint may actually have several possible representations,
    which is why this function returns a list of schemas. An example of this is
    the `Union` type hint. These are later combined via `wrap_with_any_of()`
    """
    # pylint: disable=too-many-return-statements
    type_, hint_args = parse_hint(type_)
    if type_ == Union:
        return list(itertools.chain(*map(python_type_to_json_schemas, hint_args)))
    if type_ == empty:
        return [{}]
    elif type_ in (Any, ...):
        return [{}]
    elif hasattr(type_, "__to_bus__"):
        return python_type_to_json_schemas(inspect.signature(type_.__to_bus__).return_annotation)
    elif issubclass_safe(type_, (str, bytes, complex, UUID)):
        return [{"type": "string"}]
    elif issubclass_safe(type_, Decimal):
        return [{"type": "string", "pattern": r"^-?\d+(\.\d+)?$"}]
    elif issubclass_safe(type_, (bool,)):
        return [{"type": "boolean"}]
    elif issubclass_safe(type_, (float,)):
        return [{"type": "number"}]
    elif issubclass_safe(type_, (int,)):
        return [{"type": "integer"}]
    elif issubclass_safe(type_, (Mapping,)) and hint_args and hint_args[0] == str:
        # Mapping with strings as keys
        return [
            {
                "type": "object",
                "additionalProperties": wrap_with_any_of(python_type_to_json_schemas(hint_args[1])),
            }
        ]
    elif issubclass_safe(type_, (dict, Mapping)):
        return [{"type": "object"}]
    elif issubclass_safe(type_, tuple) and hasattr(type_, "_fields"):
        # Named tuple
        return [make_custom_object_schema(type_, property_names=type_._fields)]
    elif issubclass_safe(type_, Enum) and type_.__members__:
        # Enum
        enum_first_value = list(type_.__members__.values())[0].value
        schema = {}
        try:
            schema["type"] = python_type_to_json_schemas(type(enum_first_value))[0]["type"]
            schema["enum"] = [v.value for v in type_.__members__.values()]
        except KeyError:
            logger.warning(f"Could not determine type for values in enum: {type_}")
        return [schema]
    elif issubclass_safe(type_, (Tuple,)) and hint_args:
        return [
            {
                "type": "array",
                "maxItems": len(hint_args),
                "minItems": len(hint_args),
                "items": [
                    wrap_with_any_of(python_type_to_json_schemas(sub_type))
                    for sub_type in hint_args
                ],
            }
        ]
    elif issubclass_safe(type_, (list, tuple, set)):
        schema = {"type": "array"}
        if hint_args:
            schema["items"] = wrap_with_any_of(python_type_to_json_schemas(hint_args[0]))
        return [schema]
    elif issubclass_safe(type_, NoneType) or type_ is None:
        return [{"type": "null"}]
    elif issubclass_safe(type_, (datetime.datetime)):
        return [{"type": "string", "format": "date-time"}]
    elif issubclass_safe(type_, (datetime.date)):
        return [{"type": "string", "format": "date"}]
    elif issubclass_safe(type_, (datetime.time)):
        return [{"type": "string", "format": "time"}]
    elif getattr(type_, "__annotations__", None):
        # Custom class
        return [make_custom_object_schema(type_)]
    else:
        logger.warning(
            f"Could not convert python type to json schema type: {type_}. If it is a class, "
            "ensure it's class-level variables have type hints."
        )
        return [{}]
def python_type_to_json_schemas ( type_ ) : # pylint: disable=too-many-return-statements type_ , hint_args = parse_hint ( type_ ) if type_ == Union : return list ( itertools . chain ( * map ( python_type_to_json_schemas , hint_args ) ) ) if type_ == empty : return [ { } ] elif type_ in ( Any , ... ) : return [ { } ] elif hasattr ( type_ , "__to_bus__" ) : return python_type_to_json_schemas ( inspect . signature ( type_ . __to_bus__ ) . return_annotation ) elif issubclass_safe ( type_ , ( str , bytes , complex , UUID ) ) : return [ { "type" : "string" } ] elif issubclass_safe ( type_ , Decimal ) : return [ { "type" : "string" , "pattern" : r"^-?\d+(\.\d+)?$" } ] elif issubclass_safe ( type_ , ( bool , ) ) : return [ { "type" : "boolean" } ] elif issubclass_safe ( type_ , ( float , ) ) : return [ { "type" : "number" } ] elif issubclass_safe ( type_ , ( int , ) ) : return [ { "type" : "integer" } ] elif issubclass_safe ( type_ , ( Mapping , ) ) and hint_args and hint_args [ 0 ] == str : # Mapping with strings as keys return [ { "type" : "object" , "additionalProperties" : wrap_with_any_of ( python_type_to_json_schemas ( hint_args [ 1 ] ) ) , } ] elif issubclass_safe ( type_ , ( dict , Mapping ) ) : return [ { "type" : "object" } ] elif issubclass_safe ( type_ , tuple ) and hasattr ( type_ , "_fields" ) : # Named tuple return [ make_custom_object_schema ( type_ , property_names = type_ . _fields ) ] elif issubclass_safe ( type_ , Enum ) and type_ . __members__ : # Enum enum_first_value = list ( type_ . __members__ . values ( ) ) [ 0 ] . value schema = { } try : schema [ "type" ] = python_type_to_json_schemas ( type ( enum_first_value ) ) [ 0 ] [ "type" ] schema [ "enum" ] = [ v . value for v in type_ . __members__ . values ( ) ] except KeyError : logger . warning ( f"Could not determine type for values in enum: {type_}" ) return [ schema ] elif issubclass_safe ( type_ , ( Tuple , ) ) and hint_args : return [ { "type" : "array" , "maxItems" : len ( hint_args ) , "minItems" : len ( hint_args ) , "items" : [ wrap_with_any_of ( python_type_to_json_schemas ( sub_type ) ) for sub_type in hint_args ] , } ] elif issubclass_safe ( type_ , ( list , tuple , set ) ) : schema = { "type" : "array" } if hint_args : schema [ "items" ] = wrap_with_any_of ( python_type_to_json_schemas ( hint_args [ 0 ] ) ) return [ schema ] elif issubclass_safe ( type_ , NoneType ) or type_ is None : return [ { "type" : "null" } ] elif issubclass_safe ( type_ , ( datetime . datetime ) ) : return [ { "type" : "string" , "format" : "date-time" } ] elif issubclass_safe ( type_ , ( datetime . date ) ) : return [ { "type" : "string" , "format" : "date" } ] elif issubclass_safe ( type_ , ( datetime . time ) ) : return [ { "type" : "string" , "format" : "time" } ] elif getattr ( type_ , "__annotations__" , None ) : # Custom class return [ make_custom_object_schema ( type_ ) ] else : logger . warning ( f"Could not convert python type to json schema type: {type_}. If it is a class, " "ensure it's class-level variables have type hints." ) return [ { } ]