def filter_schema(
    schema,
    ftype=None,
    embedded_doc_type=None,
    subfield=None,
    read_only=None,
    info_keys=None,
    created_after=None,
    include_private=False,
    flat=False,
    unwind=True,
    mode=None,
):
    """Filters the schema according to the given constraints.

    Args:
        schema: a dict mapping field names to :class:`Field` instances
        ftype (None): an optional field type or iterable of types to which
            to restrict the returned schema. Must be subclass(es) of
            :class:`Field`
        embedded_doc_type (None): an optional embedded document type or
            iterable of types to which to restrict the returned schema.
            Must be subclass(es) of
            :class:`fiftyone.core.odm.BaseEmbeddedDocument`
        subfield (None): an optional subfield type or iterable of subfield
            types to which to restrict the returned schema. Must be
            subclass(es) of :class:`Field`
        read_only (None): whether to restrict to (True) or exclude (False)
            read-only fields. By default, all fields are included
        info_keys (None): an optional key or list of keys that must be in the
            field's ``info`` dict
        created_after (None): an optional ``datetime`` specifying a minimum
            creation date
        include_private (False): whether to include fields that start with
            ``_`` in the returned schema
        flat (False): whether to return a flattened schema where all
            embedded document fields are included as top-level keys
        unwind (True): whether to traverse into list fields. Only applicable
            when ``flat=True``
        mode (None): whether to apply the above constraints before and/or after
            flattening the schema. Only applicable when ``flat=True``.
            Supported values are ``("before", "after", "both")``. The default
            is ``"after"``

    Returns:
        a dict mapping field names to :class:`Field` instances
    """
    has_contraints = validate_constraints(
        ftype=ftype,
        embedded_doc_type=embedded_doc_type,
        subfield=subfield,
        read_only=read_only,
        info_keys=info_keys,
        created_after=created_after,
    )

    if has_contraints:
        kwargs = dict(
            ftype=ftype,
            embedded_doc_type=embedded_doc_type,
            subfield=subfield,
            read_only=read_only,
            info_keys=info_keys,
            created_after=created_after,
        )
    else:
        kwargs = {}

    if flat:
        if mode is None:
            mode = "after"
        elif mode not in _SUPPORTED_MODES:
            raise ValueError(
                "Invalid mode=%s. Supported modes are %s"
                % (mode, _SUPPORTED_MODES)
            )

        if mode in ("before", "both"):
            before_kwargs = kwargs
        else:
            before_kwargs = {}

        if mode in ("after", "both"):
            after_kwargs = kwargs
        else:
            after_kwargs = {}
    else:
        before_kwargs = kwargs

    if has_contraints or not include_private:
        for field_name in tuple(schema.keys()):
            if (not include_private and field_name.startswith("_")) or (
                has_contraints
                and not matches_constraints(
                    schema[field_name], **before_kwargs
                )
            ):
                del schema[field_name]

    if flat:
        schema = flatten_schema(
            schema,
            **after_kwargs,
            unwind=unwind,
            include_private=include_private,
        )

    return schema
Filters the schema according to the given constraints.

    Args:
        schema: a dict mapping field names to :class:`Field` instances
        ftype (None): an optional field type or iterable of types to which
            to restrict the returned schema. Must be subclass(es) of
            :class:`Field`
        embedded_doc_type (None): an optional embedded document type or
            iterable of types to which to restrict the returned schema.
            Must be subclass(es) of
            :class:`fiftyone.core.odm.BaseEmbeddedDocument`
        subfield (None): an optional subfield type or iterable of subfield
            types to which to restrict the returned schema. Must be
            subclass(es) of :class:`Field`
        read_only (None): whether to restrict to (True) or exclude (False)
            read-only fields. By default, all fields are included
        info_keys (None): an optional key or list of keys that must be in the
            field's ``info`` dict
        created_after (None): an optional ``datetime`` specifying a minimum
            creation date
        include_private (False): whether to include fields that start with
            ``_`` in the returned schema
        flat (False): whether to return a flattened schema where all
            embedded document fields are included as top-level keys
        unwind (True): whether to traverse into list fields. Only applicable
            when ``flat=True``
        mode (None): whether to apply the above constraints before and/or after
            flattening the schema. Only applicable when ``flat=True``.
            Supported values are ``("before", "after", "both")``. The default
            is ``"after"``

    Returns:
        a dict mapping field names to :class:`Field` instances
    
fiftyone/core/fields.py