Spaces:
Running
Running
Stream canonical assets during input resolution
Browse files
app/services/input_resolver.py
CHANGED
|
@@ -350,8 +350,25 @@ class InputResolver:
|
|
| 350 |
except (CanonicalAssetNotFoundError, FileNotFoundError, ValueError) as exc:
|
| 351 |
raise InputError("Media asset was not found or is no longer available") from exc
|
| 352 |
destination = workspace.uploads / f"{uuid4().hex}_{record.filename}"
|
| 353 |
-
|
| 354 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 355 |
return InputMedia(
|
| 356 |
source=MediaSource.ASSET,
|
| 357 |
filename=record.filename,
|
|
|
|
| 350 |
except (CanonicalAssetNotFoundError, FileNotFoundError, ValueError) as exc:
|
| 351 |
raise InputError("Media asset was not found or is no longer available") from exc
|
| 352 |
destination = workspace.uploads / f"{uuid4().hex}_{record.filename}"
|
| 353 |
+
# Stream canonical media in bounded chunks. Asset resolution must never
|
| 354 |
+
# load an entire video/audio file into the worker process memory.
|
| 355 |
+
copied = 0
|
| 356 |
+
try:
|
| 357 |
+
async with (
|
| 358 |
+
aiofiles.open(source, "rb") as input_stream,
|
| 359 |
+
aiofiles.open(destination, "wb") as output_stream,
|
| 360 |
+
):
|
| 361 |
+
while chunk := await input_stream.read(1024 * 1024):
|
| 362 |
+
copied += len(chunk)
|
| 363 |
+
if copied > self.settings.max_upload_size:
|
| 364 |
+
raise InputError("Media asset exceeds MAX_UPLOAD_SIZE")
|
| 365 |
+
await output_stream.write(chunk)
|
| 366 |
+
except Exception:
|
| 367 |
+
destination.unlink(missing_ok=True)
|
| 368 |
+
raise
|
| 369 |
+
if copied != record.file_size:
|
| 370 |
+
destination.unlink(missing_ok=True)
|
| 371 |
+
raise InputError("Media asset size changed while being resolved")
|
| 372 |
return InputMedia(
|
| 373 |
source=MediaSource.ASSET,
|
| 374 |
filename=record.filename,
|