Skip to content

Commit 53716d7

Browse files
committed
fix: avoid blocking file read in file_to_base64
1 parent 05b30c1 commit 53716d7

4 files changed

Lines changed: 27 additions & 11 deletions

File tree

astrbot/core/message/components.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,14 @@ async def convert_to_base64(self) -> str:
183183
if not self.file:
184184
raise Exception(f"not a valid file: {self.file}")
185185
if self.file.startswith("file:///"):
186-
bs64_data = file_to_base64(self.file[8:])
186+
bs64_data = await file_to_base64(self.file[8:])
187187
elif self.file.startswith("http"):
188188
file_path = await download_image_by_url(self.file)
189-
bs64_data = file_to_base64(file_path)
189+
bs64_data = await file_to_base64(file_path)
190190
elif self.file.startswith("base64://"):
191191
bs64_data = self.file
192192
elif await asyncio.to_thread(os.path.exists, self.file):
193-
bs64_data = file_to_base64(self.file)
193+
bs64_data = await file_to_base64(self.file)
194194
else:
195195
raise Exception(f"not a valid file: {self.file}")
196196
bs64_data = bs64_data.removeprefix("base64://")
@@ -474,14 +474,14 @@ async def convert_to_base64(self) -> str:
474474
if not url:
475475
raise ValueError("No valid file or URL provided")
476476
if url.startswith("file:///"):
477-
bs64_data = file_to_base64(url[8:])
477+
bs64_data = await file_to_base64(url[8:])
478478
elif url.startswith("http"):
479479
image_file_path = await download_image_by_url(url)
480-
bs64_data = file_to_base64(image_file_path)
480+
bs64_data = await file_to_base64(image_file_path)
481481
elif url.startswith("base64://"):
482482
bs64_data = url
483483
elif await asyncio.to_thread(os.path.exists, url):
484-
bs64_data = file_to_base64(url)
484+
bs64_data = await file_to_base64(url)
485485
else:
486486
raise Exception(f"not a valid file: {url}")
487487
bs64_data = bs64_data.removeprefix("base64://")

astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -421,15 +421,15 @@ async def _parse_to_qqofficial(message: MessageChain):
421421
plain_text += i.text
422422
elif isinstance(i, Image) and not image_base64:
423423
if i.file and i.file.startswith("file:///"):
424-
image_base64 = file_to_base64(i.file[8:])
424+
image_base64 = await file_to_base64(i.file[8:])
425425
image_file_path = i.file[8:]
426426
elif i.file and i.file.startswith("http"):
427427
image_file_path = await download_image_by_url(i.file)
428-
image_base64 = file_to_base64(image_file_path)
428+
image_base64 = await file_to_base64(image_file_path)
429429
elif i.file and i.file.startswith("base64://"):
430430
image_base64 = i.file
431431
elif i.file:
432-
image_base64 = file_to_base64(i.file)
432+
image_base64 = await file_to_base64(i.file)
433433
else:
434434
raise ValueError("Unsupported image file format")
435435
image_base64 = image_base64.removeprefix("base64://")

astrbot/core/utils/io.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,8 @@ async def download_file(url: str, path: str, show_progress: bool = False) -> Non
201201
print()
202202

203203

204-
def file_to_base64(file_path: str) -> str:
205-
data_bytes = Path(file_path).read_bytes()
204+
async def file_to_base64(file_path: str) -> str:
205+
data_bytes = await asyncio.to_thread(Path(file_path).read_bytes)
206206
base64_str = base64.b64encode(data_bytes).decode()
207207
return "base64://" + base64_str
208208

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import base64
2+
3+
import pytest
4+
5+
from astrbot.core.utils.io import file_to_base64
6+
7+
8+
@pytest.mark.asyncio
9+
async def test_file_to_base64_reads_file_async(tmp_path):
10+
sample_file = tmp_path / "sample.bin"
11+
sample_file.write_bytes(b"astrbot")
12+
13+
result = await file_to_base64(str(sample_file))
14+
15+
expected = "base64://" + base64.b64encode(b"astrbot").decode()
16+
assert result == expected

0 commit comments

Comments
 (0)