import zipfile
import io


def open_zipfile(archive, filename, directory=None):
    """Retrieves a given file from a ZIP archive.

    Args:
        archive (:obj:`~zipfile.ZipFile`, str): The ZipFile object or path to
            the ZIP archive containing the desired file.
        filename (str): The name of the file to retrieve from the archive.
        directory (str, optional): The path to the directory within the archive
            containing the file to retrieve. Defaults to the root level of the
            archive.

    Returns:
        :obj:`~io.BytesIO`: A Python bytestream object containing the requested
        file.

    Raises:
        KeyError: If the given file could not be found within the archive.
        TypeError: If the archive is not a valid ZIP archive.

    """
    data = None
    opened = False

    if not isinstance(archive, zipfile.ZipFile):
        if not zipfile.is_zipfile(archive):
            raise TypeError("passed file does not seem to be a ZIP archive")
        else:
            archive = zipfile.ZipFile(archive, 'r')
            opened = True

    apath = filename
    if directory:
        apath = "%s/%s" % (directory, filename)

    try:
        dmpdata = archive.open(apath)
        data = io.BytesIO(dmpdata.read())
    finally:
        if opened:
            archive.close()
    return data