4
4
import mimetypes
5
5
from pathlib import Path
6
6
from typing import TYPE_CHECKING , Any
7
+ import types
7
8
8
9
if TYPE_CHECKING :
9
10
from ..foundation import Application
@@ -119,6 +120,8 @@ def data(self) -> bytes:
119
120
"""Get the response content as bytes."""
120
121
if isinstance (self .content , str ):
121
122
return bytes (self .content , "utf-8" )
123
+ if isinstance (self .content , types .GeneratorType ):
124
+ return b"" .join (self .content )
122
125
123
126
return self .content
124
127
@@ -137,6 +140,10 @@ def view(self, view: Any, status: int = 200) -> "bytes|Response":
137
140
view , status = view
138
141
self .status (status )
139
142
143
+ if isinstance (view , types .GeneratorType ):
144
+ self .status (status )
145
+ return self
146
+
140
147
if not self .get_status_code ():
141
148
self .status (status )
142
149
@@ -218,3 +225,28 @@ def download(self, name: str, location: str, force: bool = False) -> "Response":
218
225
data = filelike .read ()
219
226
220
227
return self .view (data )
228
+
229
+ def stream (self , name : str , location : str , force : bool = True , chunk_size : int = 8192 ) -> "Response" :
230
+ """Set the response as a file download response using streaming."""
231
+ self .status (200 )
232
+
233
+ # Set content type and disposition headers
234
+ self .header_bag .add (Header ("Content-Type" , "application/octet-stream" ))
235
+ self .header_bag .add (Header ("Content-Disposition" , f'attachment; filename="{ name } { Path (location ).suffix } "' ))
236
+
237
+ # Get the file size and set the Content-Length header
238
+ file_size = Path (location ).stat ().st_size
239
+ self .header_bag .add (Header ("Content-Length" , str (file_size )))
240
+
241
+ # Define the generator to stream the file in chunks
242
+ def file_generator ():
243
+ with open (location , "rb" ) as file :
244
+ while True :
245
+ chunk = file .read (chunk_size )
246
+ if not chunk :
247
+ break
248
+ yield chunk
249
+
250
+ # Set the response content as the file generator and return
251
+ self .content = file_generator ()
252
+ return self
0 commit comments