def _get_ftype_from_filename(fn, ext_unit_dict=None):
    """
    Returns the boundary flowtype and filetype for a given ModflowFlwob
    package filename.

    Parameters
    ----------
    fn : str
        The filename to be parsed.
    ext_unit_dict : dictionary, optional
        If the arrays in the file are specified using EXTERNAL,
        or older style array control records, then `f` should be a file
        handle.  In this case ext_unit_dict is required, which can be
        constructed using the function
        :class:`flopy.utils.mfreadnam.parsenamefile`.

    Returns
    -------
    flowtype : str
        Corresponds to the type of the head-dependent boundary package for
        which observations are desired (e.g. "CHD", "GHB", "DRN", or "RIV").
    ftype : str
        Corresponds to the observation file type (e.g. "CHOB", "GBOB",
        "DROB", or "RVOB").
    """

    ftype = None

    # determine filetype from filename using ext_unit_dict
    if ext_unit_dict is not None:
        for key, value in ext_unit_dict.items():
            if value.filename == fn:
                ftype = value.filetype
                break

    # else, try to infer filetype from filename extension
    else:
        ext = fn.split(".")[-1].lower()
        if "ch" in ext.lower():
            ftype = "CHOB"
        elif "gb" in ext.lower():
            ftype = "GBOB"
        elif "dr" in ext.lower():
            ftype = "DROB"
        elif "rv" in ext.lower():
            ftype = "RVOB"

    msg = f"ModflowFlwob: filetype cannot be inferred from file name {fn}"
    if ftype is None:
        raise AssertionError(msg)

    flowtype_dict = {
        "CHOB": "CHD",
        "GOBO": "GHB",
        "DROB": "DRN",
        "RVOB": "RIV",
    }
    flowtype = flowtype_dict[ftype]

    return flowtype, ftype