From 35f83697721332a5f3d1db6a0e757c0abb5838d2 Mon Sep 17 00:00:00 2001 From: Dan Coates Date: Wed, 26 Mar 2025 15:41:18 +1100 Subject: [PATCH] change back to a streaming method for web server responses PR #729 aimed to improve performance by removing the use of stream_with_context from the response handling. While this did improve performance it meant that we're now hitting the 32mb response size limit that cloud run imposes for non-streaming responses. This update reintroduces a streaming response, but using a different method that doesn't have the same small chunk size that was causing the performance issue previously. The docs on this are pretty minimal but this is pulling together some info from both the flask docs on streaming: https://flask.palletsprojects.com/en/stable/patterns/streaming/ and the fast api docs on streaming a file-like binary response: https://fastapi.tiangolo.com/advanced/custom-response/#using-streamingresponse-with-file-like-objects --- web/main.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/web/main.py b/web/main.py index 810fc460..92eda5d8 100644 --- a/web/main.py +++ b/web/main.py @@ -5,13 +5,13 @@ import logging import mimetypes import os -from typing import Optional +from typing import Generator, Optional import google.auth.transport.requests import google.cloud.storage import google.oauth2.id_token from cachetools import TTLCache, cached -from flask import Flask, abort, request, send_file +from flask import Flask, abort, request from cpg_utils.cloud import read_secret from cpg_utils.membership import is_member_in_cached_group @@ -74,7 +74,7 @@ def has_permission(email: str, dataset: str, access_file: str | None, bucket_nam @app.route('//') -def handler( +def handler( # noqa: C901 dataset: Optional[str] = None, filename: Optional[str] = None, ): @@ -142,7 +142,10 @@ def handler( blob.download_to_file(file_obj) file_obj.seek(0) - return send_file(file_obj, mimetype=content_type) + def iterfile() -> Generator[bytes, None, None]: + yield from file_obj + + return iterfile(), {'Content-Type': content_type} if __name__ == '__main__':