Return a Reponse to send the filename given.

    Arguments:
        filename: The filename (path) to send, remember to use
            :func:`safe_join`.
        mimetype: Mimetype to use, by default it will be guessed or
            revert to the DEFAULT_MIMETYPE.
        as_attachment: If true use the attachment filename in a
            Content-Disposition attachment header.
        attachment_filename: Name for the filename, if it differs
        add_etags: Set etags based on the filename, size and
            modification time.
        last_modified: Used to override the last modified value.
        cache_timeout: Time in seconds for the response to be cached.

async def send_file(
        filename: FilePath,
        mimetype: Optional[str]=None,
        as_attachment: bool=False,
        attachment_filename: Optional[str]=None,
        add_etags: bool=True,
        cache_timeout: Optional[int]=None,
        conditional: bool=False,
        last_modified: Optional[datetime]=None,
) -> Response:
    """Return a Reponse to send the filename given.

    Arguments:
        filename: The filename (path) to send, remember to use
            :func:`safe_join`.
        mimetype: Mimetype to use, by default it will be guessed or
            revert to the DEFAULT_MIMETYPE.
        as_attachment: If true use the attachment filename in a
            Content-Disposition attachment header.
        attachment_filename: Name for the filename, if it differs
        add_etags: Set etags based on the filename, size and
            modification time.
        last_modified: Used to override the last modified value.
        cache_timeout: Time in seconds for the response to be cached.

    """
    file_path = file_path_to_path(filename)
    if attachment_filename is None:
        attachment_filename = file_path.name
    if mimetype is None:
        mimetype = mimetypes.guess_type(attachment_filename)[0] or DEFAULT_MIMETYPE
    file_body = current_app.response_class.file_body_class(file_path)
    response = current_app.response_class(file_body, mimetype=mimetype)

    if as_attachment:
        response.headers.add('Content-Disposition', 'attachment', filename=attachment_filename)

    if last_modified is not None:
        response.last_modified = last_modified
    else:
        response.last_modified = datetime.fromtimestamp(file_path.stat().st_mtime)

    response.cache_control.public = True
    cache_timeout = cache_timeout or current_app.get_send_file_max_age(file_path)
    if cache_timeout is not None:
        response.cache_control.max_age = cache_timeout
        response.expires = datetime.utcnow() + timedelta(seconds=cache_timeout)

    if add_etags:
        response.set_etag(
            '{}-{}-{}'.format(
                file_path.stat().st_mtime, file_path.stat().st_size,
                adler32(bytes(file_path)),
            ),
        )

    if conditional:
        await response.make_conditional(request.range)
    return response