fix: repair Mistral OCR async upload (aiohttp.streams.FilePayload removed) (#25779)
_upload_file_async built its multipart body with
`aiohttp.streams.FilePayload(...)`, which no longer exists in aiohttp
(payload classes live in aiohttp.payload, and there is no FilePayload).
The reference sits inside a lazy closure, so import succeeds and only the
async Mistral OCR file-upload path blows up at runtime with
AttributeError on every call.
Mirror the working sync path: open the file in a context manager and let
MultipartWriter.append(file_obj, {...}) build a streaming
BufferedReaderPayload, with the POST issued inside the open() block so
the handle stays valid for the whole upload. Preserves the streaming /
memory-efficiency intent.
Found via the dependency-contract test suite (unit/deps/test_aiohttp.py),
which pins aiohttp.streams.FilePayload as absent.
This commit is contained in:
1 parent
8a016931f1
commit
c3394288bb
1 file changed
+22
-23
@@ -261,33 +261,32 @@ class MistralLoader:
|
|||||||
url = f'{self.base_url}/files'
|
url = f'{self.base_url}/files'
|
||||||
|
|
||||||
async def upload_request():
|
async def upload_request():
|
||||||
# Create multipart writer for streaming upload
|
# Open inside the request so the handle stays valid for the whole
|
||||||
writer = aiohttp.MultipartWriter('form-data')
|
# streamed POST and is closed right after.
|
||||||
|
with open(self.file_path, 'rb') as f:
|
||||||
|
writer = aiohttp.MultipartWriter('form-data')
|
||||||
|
|
||||||
# Add purpose field
|
# Add purpose field
|
||||||
purpose_part = writer.append('ocr')
|
purpose_part = writer.append('ocr')
|
||||||
purpose_part.set_content_disposition('form-data', name='purpose')
|
purpose_part.set_content_disposition('form-data', name='purpose')
|
||||||
|
|
||||||
# Add file part with streaming
|
# Stream the file. aiohttp builds a payload from the file object;
|
||||||
file_part = writer.append_payload(
|
# the previous aiohttp.streams.FilePayload was removed upstream
|
||||||
aiohttp.streams.FilePayload(
|
# (payloads live in aiohttp.payload and there is no FilePayload),
|
||||||
self.file_path,
|
# so this path raised AttributeError on every async OCR upload.
|
||||||
filename=self.file_name,
|
file_part = writer.append(f, {'Content-Type': 'application/pdf'})
|
||||||
content_type='application/pdf',
|
file_part.set_content_disposition('form-data', name='file', filename=self.file_name)
|
||||||
)
|
|
||||||
)
|
|
||||||
file_part.set_content_disposition('form-data', name='file', filename=self.file_name)
|
|
||||||
|
|
||||||
self._debug_log(f'Uploading file: {self.file_name} ({self.file_size:,} bytes)')
|
self._debug_log(f'Uploading file: {self.file_name} ({self.file_size:,} bytes)')
|
||||||
|
|
||||||
async with session.post(
|
async with session.post(
|
||||||
url,
|
url,
|
||||||
data=writer,
|
data=writer,
|
||||||
headers=self.headers,
|
headers=self.headers,
|
||||||
timeout=aiohttp.ClientTimeout(total=self.upload_timeout),
|
timeout=aiohttp.ClientTimeout(total=self.upload_timeout),
|
||||||
ssl=AIOHTTP_CLIENT_SESSION_SSL,
|
ssl=AIOHTTP_CLIENT_SESSION_SSL,
|
||||||
) as response:
|
) as response:
|
||||||
return await self._handle_response_async(response)
|
return await self._handle_response_async(response)
|
||||||
|
|
||||||
response_data = await self._retry_request_async(upload_request)
|
response_data = await self._retry_request_async(upload_request)
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user