import zipfile
import io


def open_zipfile(archive, filename, directory=None):
    """Opens and reads a certain file from a ZIP archive.

    Opens and reads a certain file from a ZIP archive. The result is
    returned as StringIO stream. filename can be a relative or absolute
    path within the ZIP archive. The optional directory argument can be
    used to supply a relative directory path, under which filename will
    be searched.

    If the filename could not be found, a KeyError will be raised.
    Raises a TypeError, if 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