basyx commited on
Commit
f764c05
·
verified ·
1 Parent(s): 67a84bf

Stream canonical assets during input resolution

Browse files
Files changed (1) hide show
  1. app/services/input_resolver.py +19 -2
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
- data = await asyncio.to_thread(source.read_bytes)
354
- await asyncio.to_thread(destination.write_bytes, data)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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,